Som*_*ser 13 ajax jquery cors http-status-code-403
我正在使用jQuery AJAX查询Web服务.我的查询如下所示:
var serviceEndpoint = 'http://example.com/object/details?version=1.1';
$.ajax({
type: 'GET',
url: serviceEndpoint,
dataType: 'jsonp',
contentType: 'jsonp',
headers: { 'api-key':'myKey' },
success: onSuccess,
error: onFailure
});
Run Code Online (Sandbox Code Playgroud)
当我执行此操作时,我得到403的状态错误.我不明白为什么我的调用导致状态代码为403.我控制了我的服务的安全性并且它被标记为全开.我知道密钥是有效的,因为我在另一个呼叫中使用它,这是有效的.以下是有效的通话:
var endpoint = 'http://example.com/object/data/item?version=1.1';
$.ajax({
type: 'POST',
url: endpoint,
cache: 'false',
contentType:'application/json',
headers: {
'api-key':'myKey',
'Content-Type':'application/json'
},
data: JSON.stringify({
id: 5,
count:true
}),
success: onDataSuccess,
error: onDataFailure
});
Run Code Online (Sandbox Code Playgroud)
我知道这是两个不同的端点.但我100%确信这不是服务器端身份验证或权限错误.再一次,服务器端的一切都是敞开的.这意味着我在客户端请求上犯了一些错误.
我觉得我应该知道这个请求是在开发期间做出的.所以,我是从http:// localhost:3000运行的.出于这个原因,我立即认为这是一个CORS问题.但一切看起来都很正确 我的POST请求有效,但我的GET并没有让我绝对感到沮丧.我错过了什么吗?会是什么呢?
yka*_*gol 20
403错误的原因是您没有发送标头.由于您正在发出CORS请求,因此除非服务器通过添加Access-Control-Allow-Headers响应来启用这些标头,否则您无法发送任何自定义标头.
在预检请求中,客户端向服务器发出2个请求.第一个是预检(使用OPTION方法),第二个是实际请求.服务器发送Access-Control-Allow-Headers标头作为预检请求的响应.因此它可以发送一些标头.通过这种方式,您的POST请求可以正常工作,因为POST请求是预检请求.但是对于GET请求,没有预检来收集Access-Control-Allow-Headers标头.因此浏览器不会发送您的自定义标头.
此问题的解决方法:
要解决此问题,请将您的dataType和contentType设置json为以下内容:
var serviceEndpoint = 'http://example.com/object/details?version=1.1';
$.ajax({
type: 'GET',
url: serviceEndpoint,
dataType: 'json',
contentType: 'json',
headers: { 'api-key':'myKey' },
success: onSuccess,
error: onFailure
});
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您的获取请求将是一个preflighted request.如果您的服务器使api-key用访问控制允许报头报头,它会工作.
上述请求的示例服务器配置(用express.js编写):
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader('Access-Control-Allow-Headers', 'api-key,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
Run Code Online (Sandbox Code Playgroud)
添加:
实际上,contentType应该是application/javascript或者application/json在执行jsonp请求时.没有contentType作为jsonp.