【问题标题】:Origin <origin> is not allowed by Access-Control-Allow-OriginAccess-Control-Allow-Origin 不允许 Origin <origin>
【发布时间】:2013-09-09 16:07:11
【问题描述】:
XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

我阅读了有关跨域 ajax 请求的信息,并了解了潜在的安全问题。在我的例子中,有 2 台服务器在本地运行,并且喜欢在测试期间启用跨域请求。

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

当我的页面从节点服务器加载时,我正在向localhost:8080 - GAE server 发出 ajax 请求。什么是最简单、最安全的(不想使用 disable-web-security 选项启动 chrome)。如果我必须更改'Content-Type',我应该在节点服务器上进行吗?怎么样?

【问题讨论】:

标签: javascript node.js ajax google-chrome cors


【解决方案1】:

由于它们在不同的端口上运行,它们是不同的 JavaScript origin。它们在同一台机器/主机名上并不重要。

您需要在服务器 (localhost:8080) 上启用 CORS。看看这个网站:http://enable-cors.org/

您需要做的就是向服务器添加一个 HTTP 标头:

Access-Control-Allow-Origin: http://localhost:3000

或者,为简单起见:

Access-Control-Allow-Origin: *

如果您的服务器尝试设置 cookie 而您使用 withCredentials = true,请不要使用“*”

在响应凭证请求时,服务器必须指定域,并且不能使用通配符。

You can read more about withCredentials here

【讨论】:

  • 如果我们想将此标头添加到 HTML 中,我们应该怎么做呢?
  • 我认为该端口不是必需的,但如果您使用的是非标准端口,例如 3000,则必须将其包含在 CORS 策略中。
  • 感谢您的回复。只是想强调使用 '*' 作为此处的值的安全含义。这允许所有来源:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… 似乎第一个示例在最少访问方面是最好的。有关如何在此处处理多个域的详细信息:stackoverflow.com/a/1850482/1566623
  • 为了清楚起见,当说您需要“向服务器添加 HTTP 标头”时,这意味着给定的 Access-Control-Allow-Origin 标头需要是 HTTP 响应的附加标头,即服务器发送。此标头必须是服务器响应的一部分,它不需要是客户端请求的一部分。具体来说,在客户端发出您想要的实际请求之前,浏览器会在它之前发送一个OPTIONS 请求,如果服务器对该OPTIONS 请求的响应不包含标头,则浏览器将不会发送您想要的请求.
  • 在 enable-cors.org 阅读后端服务器的相关提示很重要。
【解决方案2】:

如果您需要在 Chrome 中快速解决 ajax 请求,此 chrome 插件会自动允许您通过添加正确的响应标头从任何来源访问任何网站

Chrome Extension Allow-Control-Allow-Origin: *

【讨论】:

  • 我不知道为什么你没有得到更多的支持。这对于使用 Chrome 在 localhost 上进行开发的干扰最小。
  • 绝对同意。无需更改远程服务器的配置即可轻松为远程服务器启用 localhost dev。
  • @DavidBetz:当然,考虑到您验证扩展并信任它;)
  • 这应该是最佳答案!尤其是在 localhost 方面。
  • 如果这是一个好的解决方案,CORS 就不会被发明出来。将此标头应用于任何主机会禁用 CORS 保护并使您暴露于恶意脚本,而不仅仅是您的。如果您的银行账户突然空了,请不要感到惊讶。
【解决方案3】:

您必须启用 CORS 才能解决此问题

如果您的应用是使用简单的 node.js 创建的

将其设置在您的响应标头中,例如

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

如果您的应用是使用 express 框架创建的

使用 CORS 中间件,例如

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

并通过申请

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

这里有两个参考链接

  1. how-to-allow-cors-in-express-nodejs
  2. diving-into-node-js-very-first-app #查看 Ajax 部分

【讨论】:

  • 能否请您具体说明,如何使用config.allowedDomains。说在我的情况下我应该放什么uri?
  • @bsr :您可以使用* 或您想要授予访问权限的specific domain
  • 那么只有我一个得到app.configure()不是函数错误吗?
  • @PrameshBajrachaya 我没有包含“app.configure”部分——只有“app.use(allowCrossDomain)”,它对我有用。
【解决方案4】:

我接受@Rocket hazmat 的回答,因为它引导我找到解决方案。它确实在我需要设置标题的 GAE 服务器上。我必须设置这些

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

仅设置"Access-Control-Allow-Origin" 出错

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

另外,如果需要发送身份验证令牌,也添加这个

"Access-Control-Allow-Credentials" -> "true"

另外,在客户端,设置withCredentials

这会导致向服务器发送 2 个请求,其中一个是 OPTIONS。 Auth cookie 不随它一起发送,因此需要在 auth 之外进行处理。

【讨论】:

    【解决方案5】:

    在 router.js 中,只需在调用 get/post 方法之前添加代码。它对我有用,没有错误。

    //Importing modules @Brahmmeswar
    const express = require('express');
    const router = express.Router();
    
    const Contact = require('../models/contacts');
    
    router.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
      });
    

    【讨论】:

      【解决方案6】:

      如果你使用的是express,你可以使用cors中间件如下:

      var express = require('express')
      var cors = require('cors')
      var app = express()
      
      app.use(cors())
      

      【讨论】:

      【解决方案7】:

      我在使用 ajax 从 chrome 调用跨源资源时遇到问题。

      我已经使用 node js 和本地 http 服务器来部署我的 node js 应用程序。

      当我访问跨源资源时收到错误响应

      我找到了一个解决方案,

      1) 我已将以下代码添加到我的 app.js 文件中

      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      

      2) 在我的 html 页面中使用 $.getJSON(); 调用跨源资源

      $.getJSON("http://localhost:3000/users", function (data) {
          alert("*******Success*********");
          var response=JSON.stringify(data);
          alert("success="+response);
          document.getElementById("employeeDetails").value=response;
      });
      

      【讨论】:

        【解决方案8】:

        将这个添加到你的 NodeJS 服务器下面的导入:

        app.use(function(req, res, next) {
          res.header("Access-Control-Allow-Origin", "*");
          res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
          next();
        });
        

        【讨论】:

          【解决方案9】:

          如果之后得到 403,请将 WEB.XML tomcat 配置中的过滤器减少到以下内容:

          <filter>
            <filter-name>CorsFilter</filter-name>
            <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
            <init-param>
              <param-name>cors.allowed.origins</param-name>
              <param-value>*</param-value>
            </init-param>
            <init-param>
              <param-name>cors.allowed.methods</param-name>
              <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
            </init-param>
            <init-param>
              <param-name>cors.allowed.headers</param-name>
              <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
            </init-param>
            <init-param>
              <param-name>cors.exposed.headers</param-name>
              <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
            </init-param>
          </filter>
          

          【讨论】:

            【解决方案10】:

            我终于得到了apache Tomcat8的答案

            您必须编辑 tomcat web.xml 文件。

            可能会在 webapps 文件夹中,

            sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml
            

            找到并编辑它

            <web-app>
            
            
            <filter>
              <filter-name>CorsFilter</filter-name>
              <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
              <init-param>
                <param-name>cors.allowed.origins</param-name>
                <param-value>*</param-value>
              </init-param>
              <init-param>
                <param-name>cors.allowed.methods</param-name>
                <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
              </init-param>
              <init-param>
                <param-name>cors.allowed.headers</param-name>
                <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
              </init-param>
              <init-param>
                <param-name>cors.exposed.headers</param-name>
                <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
              </init-param>
              <init-param>
                <param-name>cors.support.credentials</param-name>
                <param-value>true</param-value>
              </init-param>
              <init-param>
                <param-name>cors.preflight.maxage</param-name>
                <param-value>10</param-value>
              </init-param>
            </filter>
            
            
            <filter-mapping>
              <filter-name>CorsFilter</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
            
            
            
            </web-app>
            

            这将允许 Access-Control-Allow-Origin 所有主机。 如果您需要将其从所有主机更改为仅您的主机,您可以编辑

            <param-name>cors.allowed.origins</param-name>
            <param-value>http://localhost:3000</param-value>
            

            以上代码从 * 到您的 http://your_public_IPhttp://www.example.com

            你可以参考这里Tomcat filter documentation

            谢谢

            【讨论】:

              【解决方案11】:

              如果有人在寻找解决方案,如果您在这里使用 express 是快速解决方案。

              const express = require('express')
              const cors = require('cors')
              const app = express()
              

              1) 使用 npm npm install cors --save 安装 cors

              2) 导入 [需要] const cors = require('cors')

              3) 将其用作中间件app.use(cors())

              详情insatll and usage of cors 。 就是这样,希望它有效。

              【讨论】:

                【解决方案12】:

                对于 PHP,使用它来设置标题。

                header("Access-Control-Allow-Origin: *");
                header("Access-Control-Allow-Methods: PUT, GET, POST");
                header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
                

                【讨论】:

                  【解决方案13】:

                  嗨,这是解决节点中 CORS 问题的方法只需在 Node.js 的服务器“api”端添加这些行(或者你的服务器文件), 在此之前确保安装“cors”

                      const express = require('express');
                      const app = express();
                      app.use(express.json());
                      var cors = require('cors');
                      app.use(cors());
                  

                  【讨论】:

                    【解决方案14】:
                    router.use(function(req, res, next) {
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Methods", "*");
                    res.header("Access-Control-Allow-Headers", "*");
                    next();});
                    

                    将此添加到您从前端调用的路由中。 前任- 如果您调用 http://localhost:3000/users/register,则必须将此代码片段添加到此路由所在的后端 .js 文件中。

                    【讨论】:

                      【解决方案15】:

                      使用数据类型:'jsonp',对我有用。

                         async function get_ajax_data(){
                      
                             var _reprojected_lat_lng = await $.ajax({
                      
                                                      type: 'GET',
                      
                                                      dataType: 'jsonp',
                      
                                                      data: {},
                      
                                                      url: _reprojection_url,
                      
                                                      error: function (jqXHR, textStatus, errorThrown) {
                      
                                                          console.log(jqXHR)
                      
                                                      },
                      
                                                      success: function (data) {
                      
                                                          console.log(data);
                      
                      
                      
                                                          // note: data is already json type, you just specify dataType: jsonp
                      
                                                          return data;
                      
                                                      }
                      
                                                  });
                      
                      
                      
                      
                      
                       } // function               
                      

                      【讨论】:

                        【解决方案16】:

                        【讨论】:

                          猜你喜欢
                          • 2012-06-07
                          • 2011-11-05
                          相关资源
                          最近更新 更多