我正在开发一个内部web应用程序。在IE10中,请求可以正常工作,但在Chrome中,所有的AJAX请求(有很多)都是使用OPTIONS发送的,而不是我给它的任何定义的方法。从技术上讲,我的请求是"跨域"的。该网站在localhost:6120上提供服务,我向其发出AJAX请求的服务在57124上。这个已关闭的jquery错误定义了问题,但不是真正的修复。
如何在ajax请求中使用正确的http方法?
编辑:
这是在文件加载的每一页:
jQuery.support.cors = true;
每一个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"
});
Chrome正在预处理请求以查找CORS标头。如果请求是可接受的,那么它将发送真正的请求。如果你要跨域处理,你只需要处理它,或者找到一种方法使请求不跨域。这就是为什么jQuery错误被关闭为"不会"的原因。这是经过设计的。
与简单的请求(如上所述)不同,"预先点燃"的请求优先通过OPTIONS方法向上的资源发送HTTP请求其他域,以确定实际请求是否安全发送。跨站点请求是这样预处理的,因为它们可能对用户数据有影响。特别是,请求预燃条件:
- 它使用GET、HEAD或POST以外的方法。此外,如果POST用于发送内容类型不是application/x-www-form-urlencoded、multipart/form-data或text/plain,例如,如果POST请求使用application/xml或text/xml,则该请求将被预先触发
- 它在请求中设置自定义标头(例如,请求使用诸如X-PINGOTHER之类的标头)
基于请求不是在默认端口80/443上发送的事实,此Ajax调用自动被视为跨源资源(CORS)请求,换句话说,这意味着请求自动发出OPTIONS请求,检查服务器/servlet端的CORS头。
即使设置,也会发生这种情况
crossOrigin: false;
或者即使你放弃了。
原因很简单,CCD_。尝试只将其发送到没有端口的localhost
-它将失败,因为无法访问请求的目标,但是请注意,如果域名相等,则在POST之前发送请求时没有OPTIONS请求。
我同意Kevin B的观点,错误报告说明了一切。听起来您正在尝试进行跨域ajax调用。如果您不熟悉同源政策,可以从这里开始:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript.
如果这不是一个跨域ajax调用,请尝试使目标url相对,看看问题是否消失。如果你真的很绝望,看看JSONP,但要小心,混乱潜伏着。我们真的没有什么能帮你的了。
如果可以用不同的名称通过常规GET/POST传递params,并让服务器端代码处理它。
我自己的代理绕过CORS时也遇到了类似的问题,我在Chrome中得到了同样的错误POST->OPTION。在我的情况下,它是Authorization
标头(在您的情况下是"x-li-format"
和"X-UserName"
)。我最终以伪格式传递了它(例如GET中的AuthorizatinJack
),并在调用目的地时更改了代理的代码,将其转换为标头。它在PHP中:
if (isset($_GET['AuthorizationJack'])) {
$request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack'];
}
在我的情况下,我调用由AWS(API网关)托管的API。当我试图从API自己的域以外的域调用API时,出现了错误。由于我是API所有者,我为测试环境启用了CORS,如Amazon文档中所述。
在生产中,这个错误不会发生,因为请求和api将在同一个域中。
我希望它能有所帮助!
正如@Dark Falcon的回答,我只是简单地处理了它。
在我的例子中,我使用的是node.js服务器,如果不存在,则创建一个会话。由于OPTIONS方法中没有会话详细信息,它最终为每个POST方法请求创建了一个新的会话。
因此,在我的应用程序例程中,如果不存在会话,我只添加了一个检查方法是否为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();
}
}
"preflighted"请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,以确定实际请求是否可以安全发送。跨站点请求
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
考虑使用axios
axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {
if(res.data.error) {
} else {
doAnything( res.data )
}
}).catch(function (error) {
doAnythingError(error)
});
我在使用fetch和axios时遇到了这个问题。
我遇到了一个非常类似的问题。我花了将近半天的时间来理解为什么在Firefox中一切正常,而在Chrome中却失败了。在我的情况下,这是因为我的请求标头中有重复的(或者可能键入错误的)字段。
使用fetch而不是XHR,那么即使请求是跨域的,它也不会被预激活。
$.ajax({
url: '###',
contentType: 'text/plain; charset=utf-8',
async: false,
xhrFields: {
withCredentials: true,
crossDomain: true,
Authorization: "Bearer ...."
},
method: 'POST',
data: JSON.stringify( request ),
success: function (data) {
console.log(data);
}
});
contentType:'text/plain;charset=utf-8',或者只是contentType:'text/plain',对我有用!当做