它不会呈现您的页面,因为您只是发送一个XmlHttpRequest
,仅此一项不会让您的浏览器呈现响应。
正如您从日志中看到的那样,您的 JavaScript 确实向指定的 URL 发送了 POST 请求,但由于您没有执行任何操作对该请求的响应 https://stackoverflow.com/questions/3038901/how-to-get-the-response-of-xmlhttprequest, 什么都没发生。
这会起作用...
<form action="/pastetest" method="post">
...因为提交 HTML 表单时,您的浏览器不仅仅是向以下 URL 发送 POST 请求action
,它还会更改该 URL 的位置并呈现它所获得的响应。
您会注意到,提交 HTML 表单时,浏览器地址栏中的 URL 确实发生了变化,而发送您的 HTML 表单时却没有变化。XmlHttpRequest
.
编辑,从评论中总结:
在这两种情况下,服务器都会执行这些功能image_upload
and confirm
,换句话说,从服务器的角度来看,它们是等效的,这里的主要区别在于,使用 XmlHttpRequest 方法时,浏览器不会自动呈现响应。
至于问题中描述的目标,让浏览器在两种情况下渲染结果页面,我们必须考虑在这两种情况下发生了什么XmlHttpRequest
一旦我们得到回应:
- 服务器已经执行的功能
image_upload
and confirm
- 我们渲染的模板来自
confirm
函数在我们的响应中
如果我们不介意confirm
函数被执行两次,我们可以简单地指出window.location
我们的浏览器响应URL https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL的请求。
当我们这样做时,该函数肯定会被执行两次,它已经被执行了一次以生成我们得到的响应,并且让我们的浏览器转到responseURL(在我们的例子中,这将是与confirm
函数),它将再次执行。
如果我们想防止这种情况发生,我们需要另一个解决方案。
一种选择是通知服务器我们在进行初始上传时不希望重定向到呈现的响应页面,而只需要状态信息(我们可以在此处使用 HTTP 状态代码,例如我们将 status=200 解释为成功)在我们上传时,服务器响应应该是我们需要指向的地方window.location
我们的浏览器。
这样服务器就会执行confirm
仅一次,因为在 XmlHttpRequest 的情况下它不会再自动重定向我们,相反,它只会告诉我们需要去哪里,并将实际去那里的责任留给客户端 JavaScript。
这意味着我们的服务器端代码需要改变,服务器需要辨别我们想要什么类型的响应。我们可以使用两个不同的上传端点来实现这一点,例如/pastetest
对于表单提交,以及/pastetestxhr
对于 XmlHttpRequest。
另一种选择是使用 JavaScript 从响应中提取渲染模板的部分内容,并替换当前页面的部分内容,就像从页面中删除 HTML 表单一样,并将其替换为响应中的成功通知。
为了以方便的方式做到这一点,我们可能需要使用一些客户端 JavaScript 库,例如jQuery
.
这也只会执行confirm
一次,因为在收到响应后我们不会将浏览器位置更改为该端点,而是使用我们已有的响应。
这种方法不需要更改任何服务器端代码,但会在客户端代码中引入更多复杂性。
第三种选择可能是混合方法,我们通知服务器我们不需要自动重定向,并期望我们可以将 HTML 片段作为响应插入到页面中,无需对响应进行任何复杂的解析来提取位以及我们想要插入到页面中的片段。
这需要稍微复杂一点的客户端 JavaScript(不过比上面列出的选项 2 复杂一些),以及服务器端代码更改。