如何通过 JavaScript 发送跨域 POST 请求? [英] How do I send a cross-domain POST request via JavaScript?
问题描述
如何通过 JavaScript 发送跨域 POST 请求?
How do I send a cross-domain POST request via JavaScript?
注意 - 它不应该刷新页面,之后我需要抓取并解析响应.
Notes - it shouldn't refresh the page, and I need to grab and parse the response afterwards.
推荐答案
更新: 在继续之前,每个人都应该阅读并理解 html5rocks 教程.很容易理解,也很清楚.
Update: Before continuing everyone should read and understand the html5rocks tutorial on CORS. It is easy to understand and very clear.
如果您控制正在发布的服务器,只需通过在服务器上设置响应标头来利用跨源资源共享标准".这个答案在这个线程的其他答案中讨论过,但在我看来不是很清楚.
If you control the server being POSTed, simply leverage the "Cross-Origin Resource Sharing standard" by setting response headers on the server. This answer is discussed in other answers in this thread, but not very clearly in my opinion.
简而言之,这里是您如何完成从 from.com/1.html 到 to.com/postHere.php 的跨域 POST(以 PHP 为例).注意:您只需为非 OPTIONS
请求设置 Access-Control-Allow-Origin
- 此示例始终为较小的代码片段设置所有标头.
In short here is how you accomplish the cross domain POST from from.com/1.html to to.com/postHere.php (using PHP as an example). Note: you only need to set Access-Control-Allow-Origin
for NON OPTIONS
requests - this example always sets all headers for a smaller code snippet.
在 postHere.php 中设置如下:
In postHere.php setup the following:
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://from.com': case 'https://from.com':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
这允许您的脚本进行跨域 POST、GET 和 OPTIONS.随着您继续阅读,这将变得清晰......
This allows your script to make cross domain POST, GET and OPTIONS. This will become clear as you continue to read...
从 JS(jQuery 示例)设置您的跨域 POST:
Setup your cross domain POST from JS (jQuery example):
$.ajax({
type: 'POST',
url: 'https://to.com/postHere.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
当您在第 2 步中执行 POST 时,您的浏览器会向服务器发送一个OPTIONS"方法.这是浏览器的嗅探",以查看服务器是否在您 POST 时很酷.如果请求源自http://from,则服务器以Access-Control-Allow-Origin"作为响应,告诉浏览器可以 POST|GET|ORIGIN.com"或https://from.com".由于服务器对它没问题,浏览器将发出第二个请求(这次是 POST).让您的客户端设置要发送的内容类型是一种很好的做法 - 因此您也需要允许这样做.
When you do the POST in step 2, your browser will send a "OPTIONS" method to the server. This is a "sniff" by the browser to see if the server is cool with you POSTing to it. The server responds with an "Access-Control-Allow-Origin" telling the browser its OK to POST|GET|ORIGIN if request originated from "http://from.com" or "https://from.com". Since the server is OK with it, the browser will make a 2nd request (this time a POST). It is good practice to have your client set the content type it is sending - so you'll need to allow that as well.
MDN 有一篇关于HTTP 访问控制的精彩文章,详细介绍了整个流程的工作原理.根据他们的文档,它应该在支持跨站点 XMLHttpRequest 的浏览器中工作".然而,这有点误导,因为我认为只有现代浏览器允许跨域 POST.我只在 safari、chrome、FF 3.6 上验证过这个.
MDN has a great write-up about HTTP access control, that goes into detail of how the entire flow works. According to their docs, it should "work in browsers that support cross-site XMLHttpRequest". This is a bit misleading however, as I THINK only modern browsers allow cross domain POST. I have only verified this works with safari,chrome,FF 3.6.
如果您这样做,请记住以下几点:
Keep in mind the following if you do this:
- 您的服务器每次操作必须处理 2 个请求
- 您必须考虑安全隐患.在执行诸如Access-Control-Allow-Origin: *"之类的操作之前要小心
- 这不适用于移动浏览器.根据我的经验,他们根本不允许跨域 POST.我已经测试过安卓、iPad、iPhone
- FF
- 有一个相当大的错误
- 3.6 如果服务器返回非 400 响应代码并且存在响应正文(例如验证错误),FF 3.6 将不会获得响应正文.这是一个巨大的痛苦,因为您不能使用良好的 REST 实践.请参阅错误 此处(在 jQuery 下归档,但我猜是 FF 错误 - 似乎已修复在FF4中).
- 始终返回上面的标头,而不仅仅是针对 OPTION 请求.FF 在 POST 的响应中需要它.
- Your server will have to handle 2 requests per operation
- You will have to think about the security implications. Be careful before doing something like 'Access-Control-Allow-Origin: *'
- This wont work on mobile browsers. In my experience they do not allow cross domain POST at all. I've tested android, iPad, iPhone
- There is a pretty big bug in FF < 3.6 where if the server returns a non 400 response code AND there is a response body (validation errors for example), FF 3.6 wont get the response body. This is a huge pain in the ass, since you cant use good REST practices. See bug here (its filed under jQuery, but my guess is its a FF bug - seems to be fixed in FF4).
- Always return the headers above, not just on OPTION requests. FF needs it in the response from the POST.
这篇关于如何通过 JavaScript 发送跨域 POST 请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!