Issuing POST from within a shiny app

...I have a cgi script which I am currently opening from a shiny app, using an url with the a html tag, Im currently opening this page using the GET command, with the parameters passed as arguments in the url.

I would like to do this using POST, I have tried generating an invisible form to do this, but for some reason the submit button is not working. I have tested this code on a non-shiny web site and it works correctly. Seems there is an issue in shiny on submitting forms.

Is there a preferred way of submitting POST commands using the shiny API?

POSTing a url using an a tag is not possible. https://stackoverflow.com/a/6180269/591574

I do not believe it is currently possible to POST to a Shiny app and have the app appear.

What is your end goal?

Thanks for your reply I think you misinterpreted my question:

I am trying to open a cgi script on a different server to the shiny app. I have currently implemented this using a hyperlink a tag with the GET command. However this is resulting in the cgi script arguments being visible to the user.

Ideally I would like to open the external cgi script using the POST command. I have implemented a (non-shiny) test page to do this which uses the form tag and it works correctly. However when I try and embed this same form in a shiny script it does not work in the following ways:

  1. The form submit button does not work
  2. I cannot get a handle to the form using document.GetElementById() javascript
  3. All HTML after the form does not display correctly on the page.

Is there a way of loading an external page / cgi script from a Shiny App without making arguments visible to the user? (i.e. using the POST command)

Thanks,

Chris Grace

I don't think I fully get the question still.

Current understanding:

  • Goal: Hide parameters from user
  • Need: Send parameters to external server

Then display the returned value? Then ignore the returned value? ("Open" is a vague term)

(In my past life, the results are not displayed when POSTing a form.)

Note:
With any of the solutions here, the user would be able to sniff out information if they really wanted it.


Assuming you do not want the result.

I would send the parameters back to the shiny server and have the shiny server (not the browser) do a httr::POST request to the cgi script.


Assuming you do want the result.

I would send the parameters back to the shiny server and have the shiny server (not the browser) do a httr::POST request to the cgi script. The result of this can be set to a reactive value to be displayed using uiOutput / renderUI. (If the script returns raw HTML, remember to use htmltools::HTML(txt))

This allows you to have full control over what is presented to the user and it will look / act as if the script output is native to the shiny application.


However when I try and embed this same form in a shiny script it does not work in the following ways:

  1. The form submit button does not work
  2. I cannot get a handle to the form using document.GetElementById() javascript
  3. All HTML after the form does not display correctly on the page.

This makes me want to believe that the form was malformed and the browser could not interpret it properly. There should be no reason why any of these situations are not working.


If I have still missed the problem, can you post a small reprex showing off the error? See Shiny debugging and reprex guide

Reprex here:

library(shiny)

weburl<-"Enter url for cgi script here..."

ui <- fluidPage(
tags$h1("test page"),
tags$form(method="post", action=weburl,
tags$input(type="submit", value="test"))
)
server <- function(input, output, session) {
}

shinyApp(ui = ui,server = server)

Submit button on the form is not working...

HTML generated for the form is:

<form method="post" action="Enter url...">
<input type="submit" value="test"/>
</form>

This works when I put it in a generic HTML page.

Ok. Makes sense now. Thank you for the reprex.

Offending lines: https://github.com/rstudio/shiny/blob/7e7f38005af5ed4a340954712930814e3e292ed9/srcjs/init_shiny.js#L85-L95

Unfortunately, I don't see them changing anytime soon.

Work around... Temporarily make the submit button something other than type='submit' and then change to submit after Shiny has initialized. User's should not see any difference.

The app below has implemented this and takes you to postman's website on click. (I would remove the console.log statements)

library(shiny)

weburl <- "https://postman-echo.com/post"

ui <- fluidPage(
  tags$h1("test page"),
  tags$form(method="post", action=weburl,
  tags$input(type="delay", value="test")),

  # Every 1 milli second, try to set input type to submit
  tags$script("
    var wait = function() {
      if (Shiny.setInputValue) {
        console.log('done!');
        $('input[type=\"delay\"]').attr('type', 'submit');
      } else {
        console.log('waiting');
        setTimeout(wait, 1);
      }
    }
    wait();
  ")
)

server <- function(input, output, session) { }

shinyApp(ui = ui,server = server)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.