【问题标题】:Ajax CORS Request with http 401 in preflight预检中带有 http 401 的 Ajax CORS 请求
【发布时间】:2017-11-27 21:20:05
【问题描述】:

我现在挣扎了好几个小时。我想向另一个域发出一个简单的 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 标头。这是网络流量:

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

我知道有很多关于这个主题的帖子,但似乎我缺少一些简单的东西。谁能帮帮我?

【问题讨论】:

  • dev.radbonus.com 的服务器后端需要配置为以 200 或 204 成功消息响应 OPTIONS 请求,至少对于来自 radbonus.com 的请求和至少对于路径的请求 ' /admin/affiliate-connections/retrieveSingle/45.json'。您可能想使用 stackoverflow.com/posts/44735921/edit 更新/编辑问题以添加有关在 dev.radbonus.com 的后端运行的软件的详细信息 - 因为没有这些信息,这里没有人能够进一步帮助您
  • 我明白了。你知道如何用 haproxy 做到这一点吗?因为我在网络上找不到类似的东西。

标签: javascript ajax cors http-error


【解决方案1】:

更新 看来我是不对的。 Authorization 标头永远不会为 OPTIONS 请求发送。请参阅comment by sideshowbarker - 您需要确保您的服务器没有响应401OPTIONS 的请求。

我不知道你的服务器是用什么语言编写的,但是你以错误的方式实现了授权 - OPTIONS 方法应该从身份验证中排除。另请参阅此处 - OPTIONS request authentication

以下是过时的答案:

您的服务器端需要对该请求进行 HTTP 基本身份验证。而且您不提供凭据。 401错误与CORS无关;这只是意味着服务器选择不授权您的请求,因为您没有提供身份验证凭据。

如果您尝试直接在浏览器中打开此网址(如https://dev.radbonus.com/admin/affiliate-connections/retrieveSingle/1.json),您将被要求输入登录名和密码,这是浏览器处理带有WWW-Authenticate 标头的401 错误的方式。

请注意Authorization 标头实际上并未包含在您的请求中。 所以不要使用beforeSend钩子,你应该直接在你的调用中包含标题:

headers: {
    'Authorization': 'Basic ' + btoa(username+':'+password),
},

并确保Authorization 标头出现在您的请求中。

【讨论】:

  • 但是为什么它不添加标题,即使我在发送回调之前提供了它?
  • 我的错,我没有注意到您引用了 OPTIONS 方法的标题。它从不包含授权标头。所以你应该调整你的服务器以允许未经授权的 OPTIONS 请求。请查看更新的答案。
【解决方案2】:

浏览器使用方法 - OPTIONS 发出飞行前请求,在实际 GET/POST/PUT 方法之前,您将为实际请求发送标头名称(仅限)。 这就是为什么您的 Pre-flight 请求标头看起来像这样的原因,

**Access-Control-Request-Headers:authorization,content-type**

现在,在您的服务器中,您应该为 OPTIONS 请求返回 HTTP_STATUS.OK - 200。如果它返回任何其他状态,那么您的实际请求将不会发送到服务器。

这是关于 CORS 的好读物。 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

我最近遇到了同样的问题,并通过返回 200 来解决我的 Servlet 过滤器(SpringBoot)中的 OPTIONS 方法。

【讨论】:

    【解决方案3】:

    您应该检查您是否禁用了“匿名身份验证”以允许任何身份验证,例如“Windows 身份验证”。 如果您禁用它,任何预检请求都会收到 401,因为他们不会在请求中发送凭据。

    您应该启用“匿名身份验证”并使用 IIS 中的“授权规则”部分来避免匿名访问。 如果您没有它,您可以在以下部分的 Windows 功能中安装它:

    Internet 信息服务 (IIS) - 万维网 服务 - 安全 - URL 授权

    例如,您可以像这样设置您的授权规则:

    You can read more about it here

    【讨论】:

      【解决方案4】:

      请在标头中添加跨域,如下所示:

      $.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);
              }
            });
      

      【讨论】:

      • 嘿,但是Access-Control-Allow-Origin 应该从服务器端设置,而不是从客户端设置,对吧?它已经设置好了。
      猜你喜欢
      • 2016-11-07
      • 2012-11-08
      • 2013-10-24
      • 2016-09-25
      • 2020-11-18
      • 2013-01-29
      • 2020-07-23
      • 1970-01-01
      • 2018-08-07
      相关资源
      最近更新 更多