我正在使用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 });
执行此操作时,我收到状态错误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%确信这不是服务器端身份验证或权限错误。再一次,一切在服务器端都是开放的。这意味着我在客户端请求中犯了一些错误。
我觉得我应该在开发过程中提出这个要求。因此,我正在从http:// localhost:3000运行它。因此,我立即认为这是CORS问题。但是一切看起来都是正确的。我的POST请求有效,但我的GET并没有使我感到非常沮丧。我想念什么吗?会是什么呢?
403错误的原因是 您没有发送标头 。由于正在发出CORS请求,因此除非服务器通过添加Access-Control-Allow- Headers到响应中来启用这些标头,否则无法发送任何自定义标头。
Access-Control-Allow- Headers
在preflighted-request中,客户端向服务器发出2个请求。第一个是预检(使用OPTIONS方法),第二个是实际请求。服务器发送Access- Control-Allow-Headers标头作为预检请求的响应。因此,它允许发送一些标头。通过这种方式,您的POST请求可以工作,因为POST请求是预检请求。但是对于GET请求,没有预检收集Access- Control-Allow-Headers头,并且在这种情况下浏览器不会发送您的自定义头。
解决此问题的方法:
解决方法是,将dataType和contentType设置json为以下值:
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请求将为preflighted request。如果您的服务器启用api-key带有Access-Control-Allow- Headers标头,则它将起作用。
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);
添加:
实际上,contentType应该是application/javascript或者application/json在执行jsonp请求时。没有contentType作为jsonp。
application/javascript
application/json
jsonp