【问题标题】:No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin '...' 因此不允许访问
【发布时间】:2013-12-24 09:07:28
【问题描述】:

我正在使用 .htaccess 来重写 url,并且我使用了 html 基本标记来使其工作。

现在,当我尝试发出 ajax 请求时,出现以下错误:

XMLHttpRequest 无法加载 http://www.example.com/login.php。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://example.com' 因此不允许访问。

【问题讨论】:

  • 没关系......它现在正在工作,我什至不知道是什么错误:S
  • 虽然很微妙,http://wordicious.comhttp://www.wordicious.com/ 是一个不同的域,因此出现了错误。顺便说一句,如果它现在正在工作并自行恢复,您可能应该删除该问题。
  • @acdcjunior 这似乎是错误,这是您的敏锐观察。如果您将其发布为答案,我会赞成。
  • 幸好问题没有被删除,否则我今天就看不到了!

标签: javascript jquery ajax cors xmlhttprequest


【解决方案1】:

为什么会出现错误:

JavaScript 代码受same-origin policy 的限制,这意味着,从www.example.com 的页面,您只能向位于完全 相同域的服务发出 (AJAX) 请求,在这种情况下,正好是www.example.com不是 example.com - 没有www - 或whatever.example.com)。

在您的情况下,您的 Ajax 代码正在尝试从位于 http://www.wordicious.com 的页面访问 http://wordicious.com 中的服务。

虽然非常相似,但它们不是同一个域。并且当它们不在同一个域中时,只有在目标的响应中包含Access-Control-Allow-Origin 标头时,请求才会成功。

由于您在http://wordicious.com 的页面/服务从未配置为显示此类标头,因此会显示该错误消息。

解决方案:

如前所述,源(带有 JavaScript 的页面所在的位置)和目标(JavaScript 试图到达的位置)域必须完全相同相同。

您的情况似乎是一个错字。看起来 http://wordicious.comhttp://www.wordicious.com 实际上是同一个服务器/域。因此,要修复,请同样键入目标和来源:让您的 Ajax 代码请求页面/服务到 http://www.wordicious.com 而不是 http://wordicious.com。 (可能相对地放置目标 URL,如'/login.php',不带域)。



更一般的说明:

如果问题不是像这个问题中的一个错字,解决方案是Access-Control-Allow-Origin 添加到目标域。当然,要添加它,取决于该地址背后的服务器/语言。有时,工具中的配置变量可以解决问题。其他时候你必须自己通过代码添加标题。

【讨论】:

    【解决方案2】:

    您必须将标题键/值放在选项方法响应中。 例如,如果您在 http://mydomain.com/myresource 有资源 然后,在您编写的服务器代码中

    //response handler
    void handleRequest(Request request, Response response) {
        if(request.method == "OPTIONS") {
           response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
           response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
           response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        }
    
    
    
    }
    

    【讨论】:

      【解决方案3】:

      解决方法是使用在您的“源”主机上运行的反向代理并转发到您的目标服务器,例如 Fiddler:

      链接在这里: http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

      或 Apache 反向代理...

      【讨论】:

      • 这可以在域的 Apache 或 Nginx 配置级别完成。例如,如果用户正在访问 mysite.com(没有 www)并且 XHR 正在请求 www.mysite.com,htaccess 或 httpd.conf 指令可以解决这个问题吗?
      • 当然,您的前端应用程序应该充当反向代理。例如对于 Apache,您必须安装 mod_proxy,并使用 ProxyPassReverse (httpd.apache.org/docs/current/mod/…) 配置您的规则。 Nginx 上似乎也有相同的功能:wiki.nginx.org/LikeApache
      【解决方案4】:

      对于.NET服务器可以在web.config中进行如下配置

       <system.webServer>
         <httpProtocol>
           <customHeaders>
             <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
           </customHeaders>
         </httpProtocol>
       </system.webServer>
      

      例如,如果服务器域是http://live.makemypublication.com,客户端是http://www.makemypublication.com,那么在服务器的 web.config 中进行如下配置

       <system.webServer>
         <httpProtocol>
           <customHeaders>
             <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
           </customHeaders>
        </httpProtocol>
       </system.webServer>
      

      【讨论】:

      • 更好的解决方案。谢谢
      • 非常感谢。你救了我一整天。
      • 两年后还能工作:p
      • @SyedAliTaqi 问题是 php,这就是答案被低估的原因。但是它也对我有用:)
      【解决方案5】:

      使用 addHeader 而不是使用 setHeader 方法,

      response.addHeader("Access-Control-Allow-Origin", "*");
      

      * 将允许 access to all domains


      允许access to specific domain only

      response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");
      

      检查这个blog post

      【讨论】:

      • 它显示 addheader 未定义。你能解释一下吗?
      • 这些行应该放在哪里?
      • 应该在哪里添加?
      • 那篇博文是在谈论 Node.js 和 express。不是客户端javascript。谁能确认这是否有效?
      • 我不认为这种配置只能在客户端进行..至于放在哪里,它会在服务器端代码上(大概是在构建对请求的响应时)
      【解决方案6】:

      你需要在你的 php 页面“login.php”的开头添加这个

      <?php header('Access-Control-Allow-Origin: *'); ?>
      

      【讨论】:

      • 绝对不安全。
      【解决方案7】:

      如果您从浏览器收到此错误消息:

      请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin '...' 不允许访问

      当您尝试向您无法控制的远程服务器发出 Ajax POST/GET 请求时,请忘记这个简单的修复:

      <?php header('Access-Control-Allow-Origin: *'); ?>
      

      您真正需要做的是,特别是如果您只使用 JavaScript 来执行 Ajax 请求,是一个内部代理,它接收您的查询并将其发送到远程服务器。

      首先在您的 JavaScript 中,对您自己的服务器进行 Ajax 调用,例如:

      $.ajax({
          url: yourserver.com/controller/proxy.php,
          async:false,
          type: "POST",
          dataType: "json",
          data: data,
          success: function (result) {
              JSON.parse(result);
          },
          error: function (xhr, ajaxOptions, thrownError) {
              console.log(xhr);
          }
      });
      

      然后,创建一个名为 proxy.php 的简单 PHP 文件来包装您的 POST 数据并将它们作为参数附加到远程 URL 服务器。我举一个例子说明我如何使用 Expedia 酒店搜索 API 绕过这个问题:

      if (isset($_POST)) {
        $apiKey = $_POST['apiKey'];
        $cid = $_POST['cid'];
        $minorRev = 99;
      
        $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;
      
        echo json_encode(file_get_contents($url));
       }
      

      通过做:

       echo json_encode(file_get_contents($url));
      

      您只是在服务器端执行相同的查询,之后它应该可以正常工作。

      【讨论】:

      • @NizarBsb 你疯了你知道的!!!!!! :D,非常感谢你的回答救了我的命
      【解决方案8】:

      基本上通过添加以下附加参数来更改 API 标头响应。

      访问控制允许凭据:true

      访问控制允许来源:*

      但这在安全性方面不是很好的解决方案

      【讨论】:

        【解决方案9】:

        将此添加到您的 PHP 文件或主控制器

        header("Access-Control-Allow-Origin: http://localhost:9000");
        

        【讨论】:

        • 结束 - 你还需要header("Access-Control-Allow-Credentials: true");
        【解决方案10】:

        通过 httpd.conf 中的以下条目解决

        #CORS Issue
        Header set X-Content-Type-Options "nosniff"
        Header always set Access-Control-Max-Age 1728000
        Header always set Access-Control-Allow-Origin: "*"
        Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
        Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
        Header always set Access-Control-Allow-Credentials true
        
        #CORS REWRITE
        RewriteEngine On                  
        RewriteCond %{REQUEST_METHOD} OPTIONS 
        #RewriteRule ^(.*)$ $1 [R=200,L]
        RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]
        

        【讨论】:

        • 在 Apache2、CentOS7、Larravel 5 和 React 上对我有用的唯一方法
        【解决方案11】:

        请在 Javascript 中找到 XMLHTTPREQUEST 中用于设置请求标头的函数。

        ...
        
        xmlHttp.setRequestHeader("Access-Control-Allow-Origin", "http://www.example.com");
        ...
        </script>
        
        

        参考:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader

        【讨论】:

          猜你喜欢
          • 2017-02-04
          • 2014-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-09
          • 2018-10-15
          • 2014-03-13
          相关资源
          最近更新 更多