Access-Control-Allow-Origin不允许使用Origin <origin>


182
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',是否应该在节点服务器上进行更改?怎么样?


可以在这里找到更快的解决方案:stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

Answers:


192

由于它们在不同的端口上运行,因此它们是不同的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在此处了解更多信息


如果我们想将此标头添加到HTML中,那么我们应该怎么做?
Azam Alvi

1
我认为该端口不是必需的,但是如果您使用的是非标准端口(例如3000),则必须将其包括在CORS策略中。
Michael Connor

4
感谢您的回复。只是想强调在这里使用'*'作为值的安全隐患。这允许所有来源:developer.mozilla.org/en-US/docs/Web/HTTP/Headers / ... 似乎第一个示例在访问最少的方面是最好的。有关如何在多个域中执行此操作的详细信息,请访问:stackoverflow.com/a/1850482/1566623
Christopher Kuttruff,

14
为了清楚起见,当说您需要“向服务器添加HTTP标头”时,这意味着给定的Access-Control-Allow-Origin标头需要是服务器发送的HTTP响应的添加标头。此标头必须是服务器响应的一部分,而不必是客户机的request的一部分。具体来说,是在客户端发出您想要的实际请求之前,浏览器在该OPTIONS请求之前发送了一个请求,并且如果服务器对该OPTIONS请求的响应不包含标头,则浏览器将不会发送您想要的请求。
AjaxLeung

1
请务必在enable-cors.org中阅读有关后端服务器的相关提示,这一点很重要。
卡尔斯,

69

如果您需要在Chrome中快速解决Ajax请求,则此chrome插件会自动添加适当的响应标头,使您可以从任何来源访问任何网站

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


6
我不知道为什么您没有得到更多的支持。这对于使用Chrome在localhost上进行开发的干扰最小。
大卫·贝兹

绝对同意。易于针对远程服务器启用localhost开发,而无需更改远程服务器的配置。
詹斯·韦格

@DavidBetz:当然,考虑到您验证扩展名并信任它;)
haylem

2
这应该是最重要的答案!特别是在本地主机方面。
本尼迪克特先生

16
如果这是一个好的解决方案,则不会首先发明CORS。将此标头应用于任何主机将禁用CORS保护,并使您暴露于恶意脚本,而不仅仅是您自己的脚本。如果您的银行帐户突然空了,请不要感到惊讶。
支石墓

54

您必须启用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. 如何允许在表达nodejs
  2. 深入节点 js- 非常第一的应用程序#请参阅Ajax部分

能否请您指定使用方法config.allowedDomains。说在我的情况下,我应该放在哪里?
bsr

@bsr:您可以使用*specific domain您要授予访问权限的。
mithunsatheesh 2013年

1
那我唯一得到app.configure()的不是函数错误吗?
普拉梅什·巴杰拉查亚

@PrameshBajrachaya我没有包括“ app.configure”部分,仅包括“ app.use(allowCrossDomain)”,它对我有用。
Giorgos Sfikas

8

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


7

在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();
  });

5

在使用Chrome中的Ajax调用跨源资源时,我遇到了一个问题。

我已经使用节点js和本地http服务器来部署我的节点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;
});

5

如果使用的是Express,则可以按以下方式使用cors中间件:

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

app.use(cors())

3

将此添加到导入以下的NodeJS Server中:

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();
});

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>

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_IP http://www.example.com

您可以在这里参考Tomcat过滤器文档

谢谢


1

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

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

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               

0

对于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");

0
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文件中。


0

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

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

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

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

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

有关详细信息以及cors的用法。就是这样,希望它能起作用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.