Flask - response to a POST - confusing behaviour

前端 未结 2 873
刺人心
刺人心 2021-01-27 07:26

I am completely confused by the following behaviour in Flask. I am sure there is something basic going on but I don\'t know if this is a script or a server issue, so I posted th

2条回答
  •  粉色の甜心
    2021-01-27 08:12

    It does not render your page since you are just sending an XmlHttpRequest, that alone will not have your browser rendering the response.

    Your JavaScript does send a POST request to the URL specified as you can see from your logs, but since you are not doing anything with the response to that request, nothing happens.

    This will work...

    ...because with submitting your HTML form, your browser is not just sending a POST request to the URL in action, it will also change location to that URL and render the response it is getting.

    You'll notice that when submitting the HTML form, the URL in your browser location bar does change, which it doesn't when sending your XmlHttpRequest.

    Edit, summarizing from comments:

    In both cases, the server will execute the functions image_upload and confirm, in other words from the server perspective, they are equivalent, the main difference here is that with the XmlHttpRequest method, the response is not automatically rendered by the browser.

    As for the goal described in the question, having the browser render the result page in both cases, we have to think about what happened in the XmlHttpRequest case once we have our response:

    • the server already executed functions image_upload and confirm
    • our rendered template from the confirm function is in our response

    In case we do not mind the confirm function being executed twice, we could simply point window.location of our browser to the responseURL of the request.

    The function will definitely be executed twice when we do this though, it has already been executed once in order to generate the response we got, and having our browser go to the responseURL (in our case, that will be the URL corresponding to the confirm function), it will execute again.

    If we wanted to prevent this, we would need another solution though.

    One option would be to inform the server that we do not want a redirect to the rendered response page when doing our initial upload, but instead just want a status information (we could use HTTP status code here, e.g. we interpret status=200 as success) on our upload, and the server response should be where we need to point window.location of our browser.

    This way, the server would execute confirm only once, as it would not automatically redirect us anymore in case of our XmlHttpRequest, instead it would just tell us where we need to go and leave the responsibility to actually go there to the client-side JavaScript.

    This would mean a change of our server-side code, the server would need to discern what type of response we want. We could implement this with two different endpoints for our upload, e.g. /pastetest for form submit, and /pastetestxhr for XmlHttpRequest.

    Another option would be to extract parts of the rendered template from the response using JavaScript, and replace parts of our current page, as in remove our HTML form from the page, and replace it with our success notification from the response.

    In order to do this in a convenient way, we will likely want to use some client side JavaScript libraries such as jQuery.

    This would also only execute confirm once, as we would refrain from changing browser location to that endpoint after we got our response, and instead use the response we already have.

    This approach does not require any server-side code to be changed, but introduce more complexity in our client-side code.

    A third option could be a hybrid approach, we inform the server that we do not want an automatic redirect, and expect as a response an HTML snippet we can insert in our page as is, without any complex parsing of the response to extract the bits and pieces we want to insert into our page.

    This one would require a litte more complex client-side JavaScript (less complex than our option 2 lined out above though), and server-side code change.

提交回复
热议问题