jQuery AJAX调用导致错误状态403
我正在使用jQueryAjax对web服务进行查询。我的查询如下所示:jQuery AJAX调用导致错误状态403,jquery,ajax,cors,http-status-code-403,Jquery,Ajax,Cors,Http Status Code 403,我正在使用jQueryAjax对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: onSu
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
});
当我执行此操作时,我得到一个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
});
我知道这是两个不同的端点。但我100%相信这不是服务器端身份验证或权限错误。再一次,服务器端的一切都是完全开放的。这意味着我在客户端请求上犯了一些错误
我觉得我应该告诉大家,这个请求是在开发过程中提出的。所以,我是从。出于这个原因,我立即认为这是CORS的问题。但一切看起来都是正确的。事实上,我的POST请求是有效的,但我的GET并没有让我完全失望。我错过什么了吗?可能是什么?403错误的原因是您没有发送标题。由于您正在发出CORS请求,因此无法发送任何自定义头,除非服务器通过向响应中添加
Access Control Allow headers
来启用这些头
在a中,客户端向服务器发出2个请求。第一个是飞行前(使用选项方法),第二个是实际请求。服务器发送标头作为飞行前请求的响应。因此,它允许发送一些标头。通过这种方式,您的POST请求可以工作,因为POST请求是飞行前请求。但对于GET请求,并没有预飞行来收集标题,在这种情况下,浏览器不会发送您的自定义标题
此问题的解决方法:
作为一种解决方法,将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
});
通过这种方式,get请求将是一个预飞行请求
。如果您的服务器启用带有标头的api键
,它将正常工作
上述请求的服务器配置示例(用express.js编写):
增加:
实际上,在执行jsonp请求时,contentType
应该是application/javascript
或application/json
。没有contentType
asjsonp
如果查看for jQuery的Ajax调用,它会在内容类型部分提到以下内容:
注意:对于跨域请求,请将内容类型设置为任何内容
应用程序/x-www-form-urlencoded、多部分/表单数据或
text/plain将触发浏览器发送飞行前选项
对服务器的请求
该页面并未真正提及什么是“飞行前选项请求”,但我在网上查找该短语时发现了一些有趣的链接:
- HTML5岩石
- W3C规范
我们倾向于考虑JavaScript +浏览器=客户端,但是在插图中,作者解释了Web开发者代码和浏览器开发者代码之间的区别,前者是用JavaScript代码编写的,后者是用C、C++或C代码编写的。p>
一个好的包分析器工具是,它类似于。这些工具中的任何一个都应该向您显示从浏览器发送到服务器的航班前请求。最有可能的情况是,服务器正在用一个url阻止您的Ajax请求。您是否尝试直接在浏览器中打开该url?您是否缺少url的
/data/
部分来匹配有效的部分?请注意,您不能为jsonp
请求发送标题,这是一个脚本请求。您确定要jsonp
而不是json
?还有,为什么要为标题设置JSON.stringify()
?GET没有请求contentType
。因为没有发送正文内容。你有很多问题,其中任何一个都可以problem@charlietfl我确实试过在浏览器中打开。我不熟悉需要包含的任何/data/
部分。我通常只需要传入版本
和api密钥
。我假设应该将api键
作为头。是否需要将数据
和内容类型
属性设置为jsonp
?这似乎应该是一个简单的电话。但很明显,我把事情搞砸了,忽略了一些事情。正确的调用应该是什么样的?jsonp是与ajax不同的请求类型,不允许使用头。从目前的情况来看,对这个问题的了解还不够。你们在使用chrome吗?您的后端技术是什么?res.setHeader代码应该写在哪里?另外,res是什么类型的对象?@Zoran777它将位于服务器端。对于express
server中的res
。
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);