Ajax 预检中带有 http 401 的 CORS 请求
Ajax CORS Request with http 401 in preflight
我现在挣扎了几个小时。我想向另一个域发出一个简单的 ajax 请求,但一直收到 http 401 错误:
jQuery(document).ready(function($){
var challengeid = $('#codepressHook').data('challengeid');
var clicked = false;
$('#codepressHook').click(function(){
if(!clicked){
$.ajax({
url: "https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/"+challengeid+".json",
method: "GET",
dataType: "json",
jsonp: false,
contentType: "application/json",
xhrFields: {
withCredentials: true
},
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic "+ btoa(username+":"+password));
},
success: function(data){
$('#codepressHock').html(data.data.code);
},
error: function(error){
alert(error);
}
});
}
});
});
我在服务器端设置了所有相关的 CORS headers。这是网络流量:
Request URL:https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/45.json
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:185.102.94.230:443
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, X-Requested-With, Authorization, Origin
Access-Control-Allow-Methods:POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://radbonus.com
Access-Control-Max-Age:31536000
Content-Length:463
Content-Type:text/html; charset=iso-8859-1
Date:Sat, 24 Jun 2017 11:25:33 GMT
Server:Apache/2.4.18 (Ubuntu)
WWW-Authenticate:Basic realm="Admin"
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Connection:keep-alive
Host:dev.radbonus.com
Origin:http://radbonus.com
Referer:http://radbonus.com/plugintest/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
我知道有很多关于这个主题的帖子,但我似乎遗漏了一些简单的东西。谁能帮帮我?
更新 看来我是不对的。 Authorization
header 永远不会为 OPTIONS
请求发送。请参阅 comment by sideshowbarker
- 您需要确保您的服务器不会以 401
响应 OPTIONS
请求。
我不知道你的服务器是用什么语言编写的,但是你以错误的方式实现了授权 - OPTIONS 方法应该被排除在 auth 之外。另见此处 - OPTIONS request authentication
以下是已过时的答案:
您的服务器端要求对此请求进行 HTTP 基本身份验证。而且您不提供凭据。 401错误与CORS无关;这只是意味着服务器选择不授权您的请求,因为您没有提供身份验证凭据。
如果您尝试直接在浏览器中打开此 url(如 https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/1.json),您将被要求输入登录名和密码,这是浏览器处理 WWW-Authenticate
401 错误的方式header.
请注意,Authorization
header 实际上并未包含在您的请求中。
因此,与其使用 beforeSend
钩子,不如直接在调用中包含 header:
headers: {
'Authorization': 'Basic ' + btoa(username+':'+password),
},
并确保 Authorization
header 出现在您的请求中。
Please add cross domain in headers like this:
$.ajax({
url: "https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/"+challengeid+".json",
method: "GET",
dataType: "json",
jsonp: false,
contentType: "application/json",
xhrFields: {
withCredentials: true
},
crossDomain: true,
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic "+ btoa(username+":"+password));
xhr.setRequestHeader("Access-Control-Allow-Origin",'*');
},
success: function(data){
$('#codepressHock').html(data.data.code);
},
error: function(error){
alert(error);
}
});
您应该检查是否已禁用 "Anonymous Authentication" 以允许任何身份验证,例如 "Windows Authentication"。
如果您禁用它,您将收到任何预检请求的 401,因为他们不会在请求中发送凭据。
您应该在 IIS 中启用 "Anonymous Authentication" 并使用 "Authorization Rules" 部分以避免匿名访问。
如果您没有它,您可以在 windows 部分下的功能中安装它:
Internet Information Services(IIS) - World Wide Web
Services - Security - URL Authorization
例如,您可以像这样设置您的授权规则:
浏览器使用方法 - OPTIONS 发出 Pre-flight 请求,在实际 GET/POST/PUT 方法之前,您将使用 header 名称(仅)发送实际请求。
这就是为什么您的 Pre-flight 请求 header 看起来像这样,
**Access-Control-Request-Headers:authorization,content-type**
现在,在您的服务器中,对于 OPTIONS 请求,您应该 return HTTP_STATUS.OK - 200。如果它 return 是任何其他状态,那么您的实际请求将不会发送到服务器。
这是一篇关于 CORS 的好读物。
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
我最近遇到了同样的问题,并通过 returning 解决了,我的 Servlet 过滤器 (SpringBoot) 中的 OPTIONS 方法为 200。
我现在挣扎了几个小时。我想向另一个域发出一个简单的 ajax 请求,但一直收到 http 401 错误:
jQuery(document).ready(function($){
var challengeid = $('#codepressHook').data('challengeid');
var clicked = false;
$('#codepressHook').click(function(){
if(!clicked){
$.ajax({
url: "https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/"+challengeid+".json",
method: "GET",
dataType: "json",
jsonp: false,
contentType: "application/json",
xhrFields: {
withCredentials: true
},
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic "+ btoa(username+":"+password));
},
success: function(data){
$('#codepressHock').html(data.data.code);
},
error: function(error){
alert(error);
}
});
}
});
});
我在服务器端设置了所有相关的 CORS headers。这是网络流量:
Request URL:https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/45.json
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:185.102.94.230:443
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, X-Requested-With, Authorization, Origin
Access-Control-Allow-Methods:POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://radbonus.com
Access-Control-Max-Age:31536000
Content-Length:463
Content-Type:text/html; charset=iso-8859-1
Date:Sat, 24 Jun 2017 11:25:33 GMT
Server:Apache/2.4.18 (Ubuntu)
WWW-Authenticate:Basic realm="Admin"
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Connection:keep-alive
Host:dev.radbonus.com
Origin:http://radbonus.com
Referer:http://radbonus.com/plugintest/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
我知道有很多关于这个主题的帖子,但我似乎遗漏了一些简单的东西。谁能帮帮我?
更新 看来我是不对的。 Authorization
header 永远不会为 OPTIONS
请求发送。请参阅 comment by sideshowbarker
- 您需要确保您的服务器不会以 401
响应 OPTIONS
请求。
我不知道你的服务器是用什么语言编写的,但是你以错误的方式实现了授权 - OPTIONS 方法应该被排除在 auth 之外。另见此处 - OPTIONS request authentication
以下是已过时的答案:
您的服务器端要求对此请求进行 HTTP 基本身份验证。而且您不提供凭据。 401错误与CORS无关;这只是意味着服务器选择不授权您的请求,因为您没有提供身份验证凭据。
如果您尝试直接在浏览器中打开此 url(如 https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/1.json),您将被要求输入登录名和密码,这是浏览器处理 WWW-Authenticate
401 错误的方式header.
请注意,Authorization
header 实际上并未包含在您的请求中。
因此,与其使用 beforeSend
钩子,不如直接在调用中包含 header:
headers: {
'Authorization': 'Basic ' + btoa(username+':'+password),
},
并确保 Authorization
header 出现在您的请求中。
Please add cross domain in headers like this:
$.ajax({
url: "https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/"+challengeid+".json",
method: "GET",
dataType: "json",
jsonp: false,
contentType: "application/json",
xhrFields: {
withCredentials: true
},
crossDomain: true,
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic "+ btoa(username+":"+password));
xhr.setRequestHeader("Access-Control-Allow-Origin",'*');
},
success: function(data){
$('#codepressHock').html(data.data.code);
},
error: function(error){
alert(error);
}
});
您应该检查是否已禁用 "Anonymous Authentication" 以允许任何身份验证,例如 "Windows Authentication"。 如果您禁用它,您将收到任何预检请求的 401,因为他们不会在请求中发送凭据。
您应该在 IIS 中启用 "Anonymous Authentication" 并使用 "Authorization Rules" 部分以避免匿名访问。 如果您没有它,您可以在 windows 部分下的功能中安装它:
Internet Information Services(IIS) - World Wide Web Services - Security - URL Authorization
例如,您可以像这样设置您的授权规则:
浏览器使用方法 - OPTIONS 发出 Pre-flight 请求,在实际 GET/POST/PUT 方法之前,您将使用 header 名称(仅)发送实际请求。 这就是为什么您的 Pre-flight 请求 header 看起来像这样,
**Access-Control-Request-Headers:authorization,content-type**
现在,在您的服务器中,对于 OPTIONS 请求,您应该 return HTTP_STATUS.OK - 200。如果它 return 是任何其他状态,那么您的实际请求将不会发送到服务器。
这是一篇关于 CORS 的好读物。 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
我最近遇到了同样的问题,并通过 returning 解决了,我的 Servlet 过滤器 (SpringBoot) 中的 OPTIONS 方法为 200。