223
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',我应该在节点服务器上进行吗?如何?

4

16 回答 16

243

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

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

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

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

或者,为简单起见:

Access-Control-Allow-Origin: *

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

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

withCredentials你可以在这里阅读更多

于 2013-09-05T17:59:51.490 回答
78

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

Chrome 扩展允许控制允许来源:*

于 2016-06-15T15:54:01.207 回答
62

您必须启用 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. 如何允许 cors-in-express-nodejs
  2. 潜入节点-js-very-first-app #see the Ajax section
于 2013-09-05T18:08:59.880 回答
9

我接受@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 不会随它一起发送,因此需要处理外部身份验证。

于 2013-09-05T18:42:49.410 回答
9

在 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();
  });
于 2018-10-02T04:13:11.347 回答
8

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

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

app.use(cors())
于 2019-02-16T09:50:50.503 回答
5

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

我使用 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;
});
于 2014-08-07T11:47:28.180 回答
4

将其添加到您的 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();
});
于 2018-04-17T19:47:55.923 回答
3

如果之后得到 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>
于 2018-09-29T11:43:39.573 回答
3

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

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

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

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

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

有关详细信息insatll 和 cors 的用法。就是这样,希望它有效。

于 2020-06-09T10:15:37.357 回答
2

我终于得到了 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过滤器文档

谢谢

于 2018-05-02T09:10:02.923 回答
1

对于 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");
于 2019-08-11T06:31:12.780 回答
1

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

    const express = require('express');
    const app = express();
    app.use(express.json());
    var cors = require('cors');
    app.use(cors());
于 2019-09-22T14:50:18.383 回答
1
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 文件中。

于 2020-04-24T19:02:13.243 回答
0

使用 dataType: '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               
于 2018-09-28T19:18:29.180 回答
-3

如果您使用的是 Google Chrome,请尝试安装此插件:

https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related

于 2019-07-18T23:41:21.283 回答