jQuery Chrome 中的 AJAX 发送选项而不是 GET/POST/PUT/DELETE?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21783079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE?
提问by Corey Ogburn
I am working on an internal web application at work. In IE10 the requests work fine, but in Chrome all the AJAX requests (which there are many) are sent using OPTIONS instead of whatever defined method I give it. Technically my requests are "cross domain." The site is served on localhost:6120 and the service I'm making AJAX requests to is on 57124. This closed jquery bugdefines the issue, but not a real fix.
我正在开发一个内部 Web 应用程序。在 IE10 中,请求工作正常,但在 Chrome 中,所有 AJAX 请求(有很多)都是使用 OPTIONS 而不是我给它定义的任何方法发送的。从技术上讲,我的请求是“跨域”。该站点在 localhost:6120 上提供服务,我向其发出 AJAX 请求的服务在 57124 上。这个关闭的 jquery 错误定义了问题,但不是真正的修复。
What can I do to use the proper http method in ajax requests?
我该怎么做才能在 ajax 请求中使用正确的 http 方法?
Edit:
编辑:
This is in the document load of every page:
这是在每个页面的文档加载中:
jQuery.support.cors = true;
And every AJAX is built similarly:
每个 AJAX 的构建方式都类似:
var url = 'http://localhost:57124/My/Rest/Call';
$.ajax({
url: url,
dataType: "json",
data: json,
async: true,
cache: false,
timeout: 30000,
headers: { "x-li-format": "json", "X-UserName": userName },
success: function (data) {
// my success stuff
},
error: function (request, status, error) {
// my error stuff
},
type: "POST"
});
回答by Dark Falcon
Chrome is preflighting the request to look for CORSheaders. If the request is acceptable, it will then send the real request. If you're doing this cross-domain, you will simply have to deal with it or else find a way to make the request non-cross-domain. This is why the jQuery bug was closed as won't-fix. This is by design.
Chrome 正在预先检查查找CORS标头的请求。如果请求是可以接受的,它就会发送真正的请求。如果您要跨域进行此操作,则只需处理它,或者找到一种使请求非跨域的方法。这就是 jQuery 错误因无法修复而关闭的原因。这是设计使然。
Unlike simple requests (discussed above), "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:
- It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
- It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
与简单请求(上面讨论过)不同,“预检”请求首先通过 OPTIONS 方法向其他域上的资源发送 HTTP 请求,以确定实际请求是否可以安全发送。跨站点请求是这样预检的,因为它们可能会对用户数据产生影响。特别是,在以下情况下对请求进行预检:
- 它使用 GET、HEAD 或 POST 以外的方法。此外,如果 POST 用于发送内容类型不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 的请求数据,例如,如果 POST 请求向服务器发送 XML 负载使用 application/xml 或 text/xml,然后预检请求。
- 它在请求中设置自定义标头(例如,请求使用 X-PINGOTHER 等标头)
回答by Dropout
Based on the fact that the request isn't sent on the default port 80/443 this Ajax call is automatically considered a cross-origin resource (CORS) request, which in other words means that the request automatically issues an OPTIONS request which checks for CORS headers on the server's/servlet's side.
基于请求不是在默认端口 80/443 上发送这一事实,这个 Ajax 调用会自动被视为跨域资源 (CORS) 请求,换句话说,该请求会自动发出一个 OPTIONS 请求来检查服务器/servlet 端的 CORS 标头。
This happens even if you set
即使您设置,也会发生这种情况
crossOrigin: false;
or even if you ommit it.
或者即使你省略它。
The reason is simply that localhost != localhost:57124
. Try sending it only to localhost
without the port - it will fail, because the requested target won't be reachable, however notice that if the domain names are equalthe request is sent without the OPTIONS request before POST.
原因很简单localhost != localhost:57124
。尝试仅将其发送到localhost
没有端口的情况 - 它会失败,因为将无法访问请求的目标,但是请注意,如果域名相同,则在 POST 之前发送请求时没有 OPTIONS 请求。
回答by jgitter
I agree with Kevin B, the bug report says it all. It sounds like you are trying to make cross-domain ajax calls. If you're not familiar with the same origin policy you can start here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript.
我同意 Kevin B 的观点,错误报告说明了一切。听起来您正在尝试进行跨域 ajax 调用。如果您不熟悉同源策略,您可以从这里开始:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript。
If this is not intended to be a cross-domain ajax call, try making your target url relative and see if the problem goes away. If you're really desperate look into the JSONP, but beware, mayhem lurks. There really isn't much more we can do to help you.
如果这不是跨域 ajax 调用,请尝试使您的目标 url 相对并查看问题是否消失。如果你真的很想看看 JSONP,但要小心,潜伏着混乱。我们真的没有更多可以帮助您的了。
回答by Aidin
If it is possible pass the params through regular GET/POST with a different name and let your server side code handles it.
如果可以使用不同的名称通过常规 GET/POST 传递参数,并让您的服务器端代码处理它。
I had a similar issue with my own proxy to bypass CORS and I got the same error of POST->OPTION in Chrome. It was the Authorization
header in my case ("x-li-format"
and "X-UserName"
here in your case.) I ended up passing it in a dummy format (e.g. AuthorizatinHyman
in GET) and I changed the code for my proxy to turn that into a header when making the call to the destination. Here it is in PHP:
我自己的代理在绕过 CORS 时遇到了类似的问题,并且在 Chrome 中遇到了相同的 POST->OPTION 错误。这是Authorization
在我的情况标题("x-li-format"
和"X-UserName"
在这里你的情况)。最后我通过它在一个虚拟的格式(例如AuthorizatinHyman
在GET),我改变了代码进行调用到目的地时,我的代理把它转换成一个头. 这是在PHP中:
if (isset($_GET['AuthorizationHyman'])) {
$request_headers[] = "Authorization: Basic ".$_GET['AuthorizationHyman'];
}
回答by gbonesso
In my case I'm calling an API hosted by AWS (API Gateway). The error happened when I tried to call the API from a domain other than the API own domain. Since I'm the API owner I enabled CORS for the test environment, as described in the Amazon Documentation.
就我而言,我正在调用由 AWS(API 网关)托管的 API。当我尝试从 API 自己的域以外的域调用 API 时发生错误。由于我是 API 所有者,因此我为测试环境启用了 CORS,如Amazon 文档中所述。
In production this error will not happen, since the request and the api will be in the same domain.
在生产中这个错误不会发生,因为请求和 api 将在同一个域中。
I hope it helps!
我希望它有帮助!
回答by Mahesh
As answeredby @Dark Falcon, I simply dealt with it.
正如@Dark Falcon所回答的,我只是处理了它。
In my case, I am using node.js server, and creating a session if it does not exist. Since the OPTIONS method does not have the session details in it, it ended up creating a new session for every POST method request.
就我而言,我使用的是 node.js 服务器,如果它不存在,则创建一个会话。由于 OPTIONS 方法中没有会话详细信息,因此它最终为每个 POST 方法请求创建了一个新会话。
So in my app routine to create-session-if-not-exist, I just added a check to see if method is OPTIONS
, and if so, just skip session creating part:
所以在我的应用程序创建会话如果不存在的例程中,我只是添加了一个检查以查看方法是否为OPTIONS
,如果是,则跳过会话创建部分:
app.use(function(req, res, next) {
if (req.method !== "OPTIONS") {
if (req.session && req.session.id) {
// Session exists
next();
}else{
// Create session
next();
}
} else {
// If request method is OPTIONS, just skip this part and move to the next method.
next();
}
}
回答by Noorullah
"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests
“预检”请求首先通过 OPTIONS 方法向其他域上的资源发送 HTTP 请求,以确定实际请求是否可以安全发送。跨站请求
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
回答by Evhz
Consider using axios
考虑使用axios
axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {
if(res.data.error) {
} else {
doAnything( res.data )
}
}).catch(function (error) {
doAnythingError(error)
});
I had this issue using fetchand axios worked perfectly.
我在使用fetch 时遇到了这个问题,axios 工作得很好。
回答by Andrew Tatomyr
I've encountered a very similar issue. I spent almost half a day to understand why everything works correctly in Firefox and fails in Chrome. In my case it was because of duplicated (or maybe mistyped) fields in my request header.
我遇到了一个非常相似的问题。我花了将近半天时间才明白为什么在 Firefox 中一切正常,而在 Chrome 中却失败了。就我而言,这是因为我的请求标头中的字段重复(或可能输入错误)。
回答by Fei Sun
Use fetch instead of XHR,then the request will not be prelighted even it's cross-domained.
使用 fetch 而不是 XHR,那么即使它是跨域的,请求也不会被预点亮。