jQuery AJAX 调用导致错误状态 403
jQuery AJAX call results in error status 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
});
当我执行此操作时,出现状态错误 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 错误的原因是 您没有发送 headers。由于您正在发出 CORS 请求,因此您不能发送任何自定义 header,除非服务器通过在响应中添加 Access-Control-Allow-Headers
来启用这些 header。
在 preflighted-request, client makes 2 requests to the server. First one is preflight (with OPTIONS method) and the second one is the real request. The server sends Access-Control-Allow-Headers header as a response of the preflight request. So it enables some headers to be sent. By this way your POST request can work because the POST request is a preflight-request. But for a GET request, there is no preflight to gather Access-Control-Allow-Headers header 中,在这种情况下浏览器不会发送您的自定义 header。
此问题的解决方法:
作为解决方法,将 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
});
通过这种方式,您的获取请求将是一个preflighted request
。如果您的服务器启用 api-key
和 Access-Control-Allow-Headers header,它将起作用。
上述请求的示例服务器配置(写在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);
已添加:
实际上,在执行 jsonp 请求时,contentType
应该是 application/javascript
或 application/json
。没有 contentType
作为 jsonp
.
如果您查看 jQuery 的 Ajax 调用的 API page,它会在 Content-Type 部分提到以下内容:
Note: For cross-domain requests, setting the content type to anything
other than application/x-www-form-urlencoded, multipart/form-data, or
text/plain will trigger the browser to send a preflight OPTIONS
request to the server.
该页面并没有真正提到 "preflight OPTIONS request" 是什么,但我在网上查找该短语时发现了一些有趣的链接:
- Preflight Blob Request
- HTML 5 块岩石 Using CORS
- W3C 的 Cross-Origin Resource Sharing 规范
- Using CORS for Cross-Domain Ajax Requests
有趣的是 HTML5Rocks 页面上的 code example & the CORS image。该图显示了 Ajax 调用是如何从 JavaScript 代码调用到浏览器到服务器的,以及响应如何在所有 3 个代码之间往返。
我们倾向于认为JavaScript + Browser = Client,但是图中作者在说明web开发者代码和浏览器开发者代码的区别,前者写在JavaScript 代码,但后者是使用 C、C++ 或 C# 代码编写的。
一个好的数据包分析器工具是 Fiddler, which would be similar to Wireshark. Either one of those tools, should show you the pre-flight requests which are being sent from the browser to the server. Most likely, that's where your Ajax request is being blocked at by the server with a 403 Forbidden error。
我正在使用 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 错误的原因是 您没有发送 headers。由于您正在发出 CORS 请求,因此您不能发送任何自定义 header,除非服务器通过在响应中添加 Access-Control-Allow-Headers
来启用这些 header。
在 preflighted-request, client makes 2 requests to the server. First one is preflight (with OPTIONS method) and the second one is the real request. The server sends Access-Control-Allow-Headers header as a response of the preflight request. So it enables some headers to be sent. By this way your POST request can work because the POST request is a preflight-request. But for a GET request, there is no preflight to gather Access-Control-Allow-Headers header 中,在这种情况下浏览器不会发送您的自定义 header。
此问题的解决方法:
作为解决方法,将 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
});
通过这种方式,您的获取请求将是一个preflighted request
。如果您的服务器启用 api-key
和 Access-Control-Allow-Headers header,它将起作用。
上述请求的示例服务器配置(写在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);
已添加:
实际上,在执行 jsonp 请求时,contentType
应该是 application/javascript
或 application/json
。没有 contentType
作为 jsonp
.
如果您查看 jQuery 的 Ajax 调用的 API page,它会在 Content-Type 部分提到以下内容:
Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.
该页面并没有真正提到 "preflight OPTIONS request" 是什么,但我在网上查找该短语时发现了一些有趣的链接:
- Preflight Blob Request
- HTML 5 块岩石 Using CORS
- W3C 的 Cross-Origin Resource Sharing 规范
- Using CORS for Cross-Domain Ajax Requests
有趣的是 HTML5Rocks 页面上的 code example & the CORS image。该图显示了 Ajax 调用是如何从 JavaScript 代码调用到浏览器到服务器的,以及响应如何在所有 3 个代码之间往返。
我们倾向于认为JavaScript + Browser = Client,但是图中作者在说明web开发者代码和浏览器开发者代码的区别,前者写在JavaScript 代码,但后者是使用 C、C++ 或 C# 代码编写的。
一个好的数据包分析器工具是 Fiddler, which would be similar to Wireshark. Either one of those tools, should show you the pre-flight requests which are being sent from the browser to the server. Most likely, that's where your Ajax request is being blocked at by the server with a 403 Forbidden error。