没有“Access-Control-Allow-Origin” – 节点/ Apache端口问题
我使用Node / Express创build了一个小的API,并试图使用Angularjs来获取数据,但是当我的html页面在localhost上的apache下运行时:8888和node API在端口3000上侦听,我得到了No Access-允许来源。 我尝试使用node-http-proxy和Vhosts Apache,但没有太多的成功,请看下面的完整的错误和代码。
“XMLHttpRequest无法加载localhost:3000,请求的资源上没有”Access-Control-Allow-Origin“标头,因此Origin'localhost:8888'不允许访问。
// Api Using Node/Express var express = require('express'); var app = express(); var contractors = [ { "id": "1", "name": "Joe Blogg", "Weeks": 3, "Photo": "1.png" } ]; app.use(express.bodyParser()); app.get('/', function(req, res) { res.json(contractors); }); app.listen(process.env.PORT || 3000); console.log('Server is running on Port 3000') // Angular code angular.module('contractorsApp', []) .controller('ContractorsCtrl', function($scope, $http,$routeParams) { $http.get('localhost:3000').success(function(data) { $scope.contractors = data; }) // HTML <body ng-app="contractorsApp"> <div ng-controller="ContractorsCtrl"> <ul> <li ng-repeat="person in contractors">{{person.name}}</li> </ul> </div> </body>
尝试将以下中间件添加到您的NodeJS / Express应用程序(为了您的方便,我添加了一些注释):
// Add headers app.use(function (req, res, next) { // Website you wish to allow to connect res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888'); // Request methods you wish to allow res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // Request headers you wish to allow res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // Set to true if you need the website to include cookies in the requests sent // to the API (eg in case you use sessions) res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); });
希望有所帮助!
接受的答案是好的,如果你更喜欢短的东西,你可以使用一个名为Cors Express.js的插件
使用起来很简单,在这种情况下:
var cors = require('cors'); // use it before all route definitions app.use(cors({origin: 'http://localhost:8888'}));
另一种方法是简单地将标题添加到您的路线:
router.get('/', function(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,contenttype'); // If needed res.setHeader('Access-Control-Allow-Credentials', true); // If needed res.send('cors problem fixed:)'); });
最好的答案对我来说很好,除了我需要将多个域名列入白名单。
此外,最好的答案患有OPTIONS
请求不是由中间件处理,你不会自动得到它。
我将存储在白名单中的域作为Expressconfiguration文件中的allowed_origins
存储,并根据origin
标题放置正确的域,因为Access-Control-Allow-Origin
不允许指定多个域。
以下是我最终的结果:
var _ = require('underscore'); function allowCrossDomain(req, res, next) { res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); var origin = req.headers.origin; if (_.contains(app.get('allowed_origins'), origin)) { res.setHeader('Access-Control-Allow-Origin', origin); } if (req.method === 'OPTIONS') { res.send(200); } else { next(); } } app.configure(function () { app.use(express.logger()); app.use(express.bodyParser()); app.use(allowCrossDomain); });
答案代码只允许localhost:8888。 此代码不能部署到生产,或不同的服务器和端口名称。
为了让它适用于所有的来源,请使用下面的代码:
// Add headers app.use(function (req, res, next) { // Website you wish to allow to connect res.setHeader('Access-Control-Allow-Origin', '*'); // Request methods you wish to allow res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // Request headers you wish to allow res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // Set to true if you need the website to include cookies in the requests sent // to the API (eg in case you use sessions) res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); });
你可以使用“$ http.jsonp”
要么
下面是为本地testing铬的工作
你需要用下面的命令打开你的chrome。 (按窗口+ R)
Chrome.exe --allow-file-access-from-files
注意:您的Chrome不得打开。 当你运行这个命令时,chrome会自动打开。
如果您在命令提示符中input此命令,则select您的chrome安装目录,然后使用此命令。
下面的脚本代码为MAC打开铬“ – 允许文件访问从文件”
set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" set switch to " --allow-file-access-from-files" do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
第二select
您可以使用open(1)添加标志:open -a'Google Chrome'–args – 允许从文件访问文件
app.all('*', function(req, res,next) { /** * Response settings * @type {Object} */ var responseSettings = { "AccessControlAllowOrigin": req.headers.origin, "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name", "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS", "AccessControlAllowCredentials": true }; /** * Headers */ res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials); res.header("Access-Control-Allow-Origin", responseSettings.AccessControlAllowOrigin); res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with"); res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods); if ('OPTIONS' == req.method) { res.send(200); } else { next(); } });
/** * Allow cross origin to access our /public directory from any site. * Make sure this header option is defined before defining of static path to /public directory */ expressApp.use('/public',function(req, res, next) { res.setHeader("Access-Control-Allow-Origin", "*"); // Request headers you wish to allow res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); // Set to true if you need the website to include cookies in the requests sent res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); }); /** * Server is about set up. Now track for css/js/images request from the * browser directly. Send static resources from "./public" directory. */ expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.