我正在尝试使用 json-server、Node 和 Express 在 localhost 上为我的 Angular 应用程序模拟 RESTFUL API。随之而来的 CORS 问题
Posted
技术标签:
【中文标题】我正在尝试使用 json-server、Node 和 Express 在 localhost 上为我的 Angular 应用程序模拟 RESTFUL API。随之而来的 CORS 问题【英文标题】:I'm attempting to use json-server, Node, and Express to mock a RESTFUL API for my Angular app on localhost. CORS issues have ensued 【发布时间】:2015-07-02 14:14:40 【问题描述】:基本上,我需要使用 json-server 运行 Node/Express 服务器来模拟我正在开发的测试 Angular 应用程序的 RESTFUL API。问题是谷歌浏览器抛出一个错误,表明我遇到了 CORS 问题。我尝试以解决 CORS 问题的方式配置我的服务器。 . .
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();
);
。 . .无济于事。
在不摆弄 JSONP 或以任何方式更改我的 Angular 代码的情况下,我还能做些什么吗?它似乎在 Rails 服务器上运行良好。
编辑:正如许多人所建议的那样,我尝试使用 cors 模块来解决这个问题,但这似乎也不起作用。这是我的 server.js 文件:
var express = require('express');
var app = express();
var path = require("path");
var jsonServer = require("json-server");
var databaseServer = jsonServer.create();
var cors = require("cors");
app.use(cors());
app.use("/", express.static(__dirname));
var server = app.listen(3000, function ()
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
);
var object =
"fighters": [
"id": 1,
"firstName": "Jose",
"lastName": "Aldo",
"nickname": "Scarface",
"wins": 25,
"losses": 1,
"draws": 0,
"imageUrl": "/images/jose_aldo.png"
,
"id": 2,
"firstName": "Conor",
"lastName": "McGregor",
"nickname": "",
"wins": 17,
"losses": 2,
"draws": 0,
"imageUrl": "/images/conor_mcgregor.png"
]
;
databaseServer.use(jsonServer.defaults);
databaseServer.use(jsonServer.router(object));
databaseServer.listen(4000);
这是我的 Angular 服务:
var FighterService = angular.module("FighterService", ["ngResource"]);
FighterService.factory("Fighter", ["$resource", function ($resource)
return $resource("localhost:4000/fighters/:fighterId",
fighterId : "@id" ,
query:
method: "GET",
params: fighterId: "@id" ,
isArray: true
,
get: method: "GET"
);
]);
【问题讨论】:
Chrome 给你的具体错误是什么? XMLHttpRequest 无法加载 localhost:4000/fighters.json。跨源请求仅支持协议方案:http、data、chrome、chrome-extension、https、chrome-extension-resource.b @ angular.js:9866。 . . 您的 Angular 应用程序是否由同一台服务器托管? 没有。我不知道如何设置它,以便数据库和应用程序都从同一台服务器提供服务。我已经在上面添加了我的服务器文件。 【参考方案1】:已解决
线索在错误中:
XMLHttpRequest 无法加载 localhost:4000/fighters.json。跨源请求仅支持协议方案:http、data、chrome、chrome-extension、https、chrome-extension-resource.b
在你的 Angular 中,一行
return $resource("localhost:4000/fighters/:fighterId",
认为您指的是使用协议“localhost:”的 URL。
它应该是一个绝对的 HTTP URL:
return $resource("http://localhost:4000/fighters/:fighterId",
有了你已经拥有的正确 CORS 支持,它就可以工作。
【讨论】:
【参考方案2】:如果您使用 Json-Server 来提供您的 api,您可以禁用 Cors。
查看 json-server 文档https://github.com/typicode/json-server。
本质上,json-server 中间件默认为noCors: false
我认为您可以更改它并将其设置为noCors: true
可能是这样的:
const server = jsonServer.create();
const middlewares = jsonServer.defaults( noCors: true )
// set default middlewares (logger, static, cors and no-cache)
server.use(middlewares);
【讨论】:
【参考方案3】:如果你想在 Express 上使用 CORS,你需要启用 cors 并配置
var cors = require('cors');
var whitelist = [
'http://localhost', // add here the url when you access to your angular app
'http://localhost:8080',
'http://otherdomain.com'
];
var corsOptions =
credentials: true,
origin: function(origin, callback)
var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
callback(null, originIsWhitelisted);
,
methods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE'],
allowedHeaders: 'accept, content-type'
;
app.use(cors(corsOptions));
例如,我在 3000 端口上运行 express 服务器并且我的应用程序可以在端口 8080 上运行并且工作正常,或者我的应用程序可以在 http://otherdomain.com 上运行并且也可以工作。
【讨论】:
我使用过app.use(auth);
和const auth = require("json-server-auth");
,如何添加自定义cors 设置标题以允许标题【参考方案4】:
如果只有您需要进行测试,最简单的方法可能是使用--disable-web-security
打开 Chrome,这样浏览器就不需要 CORS 标头来将数据视为安全。 (h/t @Taran)
如果其他人也需要测试,最简单的方法可能是使用the cors module。
如果您想使用自己的 Express 中间件来处理它,我前段时间也做过同样的事情。这就是我想出的。用这个替换你上面的 Express 中间件:
app.use(function (req, res, next)
'use strict';
res.header('Access-Control-Allow-Origin', '*');
if (req.headers['access-control-request-method'])
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
if (req.headers['access-control-request-headers'])
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
if (req.method === 'OPTIONS')
res.sendStatus(200);
else
next();
);
如果您需要更多上下文,代码是here。
【讨论】:
是的。我已经用我的服务器端代码更新了我的原始帖子。【参考方案5】:如果只是为了测试,您可以通过 --disable-web-security
开关启动 Chome 来告诉 Chome 接受 CORS。
【讨论】:
【参考方案6】:您需要通过在您的 express 应用中添加 cors
模块来启用 cors。使用npm
命令下载其依赖项。
并在您的 node.js 文件中添加以下行。
var cors = require('cors');
app.use(cors());
【讨论】:
@MichaelP。您已在服务器端节点文件中添加了这些行吗? 请看一下这个。您正在尝试打开文件,这就是发生协议错误的原因。 ***.com/questions/27742070/… 看。 . .如果你不介意,请站在一边。这可能是解决方案。 :-D 好的。我不确定这如何解决问题。我看到它会给我另一个服务器,但我不确定它如何让我绕过 CORS 问题。 确保您的 fighters.json 文件位于您的节点服务器项目中?【参考方案7】:在我看来(眯起眼睛)你应该能够通过模拟服务器为你提供 Angular 应用程序并解决你的问题..
- app.use("/", express.static(__dirname));
+ app.use("/angular_app", express.static(__dirname));
然后将您的 Angular 应用程序目录链接到运行模拟服务器的 /angular_app。
ln -s angular/app ../mock/angular_app
您应该能够在 localhost:4000/(或者是 :3000?)访问您的 Angular 应用程序
【讨论】:
以上是关于我正在尝试使用 json-server、Node 和 Express 在 localhost 上为我的 Angular 应用程序模拟 RESTFUL API。随之而来的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章