我正在尝试将我的Angular应用程序与Express上的简单REST服务器连接起来。服务器仅发送json
数据以回复请求。要添加CORS
支持,我使用了来自npm的cors
模块。在Angular应用中,我按照此问题的说明添加了HttpHeaders
:Angular CORS request blocked。
这是我在快递中的代码,我在其中设置了cors选项: `
// async CORS setup delegation
function corsOptsDelegator(req, cb) {
let opts = {},
origin = req.header('Origin');
if(imports.allowedOrigins.indexOf(origin) === 1) opts.origin = true;
else opts.origin = false;
opts.optionsSuccessStatus = 200;
opts.methods = ['POST', 'GET']; // allowed methods
opts.credentials = true; // for passing/setting cookie
opts.allowedHeaders = ['Content-Type', 'Accept', 'Access-Control-Allow-Origin']; // restrict headers
opts.exposedHeaders = ['Accept', 'Content-Type']; // for exposing custom headers to clients; use for hash
cb(null, opts);
}
`
以下是我将其添加到全局get
处理程序的方法:
`
app.get('/', cors(corsOptsDelegator), (res, req, nxt) => {
// only for adding cors on all requests
nxt();
});
`
以下是我如何设置Angular服务:
`
export class ContentGetterService {
private root: string;
private corsHeaders: HttpHeaders;
//private contents: string;
constructor(private http: HttpClient) {
this.root = 'http://localhost:8888';
this.corsHeaders = new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Origin': 'http://localhost:4200'
});
//this.contents = '';
}
getContent(subs: Array<string>): Observable<IContent> {
return (() => {
return this.http.get<IContent>( (() => {
let r = this.root;
subs.forEach((s, i, a) => {
if(i === a.length-1) {
r += s;
}
else {
if(s !== '/') {
r += s;
}
}
});
return r;
})(), {
headers: this.corsHeaders
});
})();
}
}
浏览器警告:Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8888/. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
感谢。
答案 0 :(得分:1)
如果您使用的是angular-cli,则可以使用代理:
{
"/api": {
"target": "http://localhost:8888",
"secure": false
}
}
将带有/api
前缀的所有请求重定向到localhost:8888,不会出现任何问题。
官方文档: https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md
答案 1 :(得分:1)
首先,客户端的问题是由于Firefox选择处理飞行前CORS的行为。不使用GET
方法,而是使用OPTIONS
方法。从我的代码中可以看出,我没有处理OPTIONS
的任何处理程序。经过一些谷歌搜索,我在github上发现了这篇文章:Express CORS middleware。使用它并对我的客户端请求标题进行以下修改,我能够正确地启动并运行它。这是代码:
CORS中间件:
function myCors(req, res, nxt) {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
res.header('Access-Control-Allow-Methods', 'GET,PUT,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Origin, Content-Type, Accept, Accept-Language, Origin, User-Agent');
if(req.method === 'OPTIONS') {
res.sendStatus(204);
}
else {
nxt();
}
}`
将其挂载到app实例:
app.use(myCors);
在Angular客户端服务上:
this.corsHeaders = new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Origin': 'http://localhost:8888/'
});
// ... adding it to the request
getContent(subs: Array<string>): Observable<IContent> {
return (() => {
return this.http.get<IContent>( (() => {
let r = this.root;
subs.forEach((s, i, a) => {
if(i === a.length-1) {
r += s;
}
else {
if(s !== '/') {
r += s;
}
}
});
return r;
})(), {
headers: this.corsHeaders
});
})();
}
感谢大家的时间和精力。
答案 2 :(得分:0)
允许您从角度JS中获取服务器端,在这种情况下,您需要允许http://localhost:8888/
,因为这是您的服务器端URL,http://localhost:4200
上的角度运行。请查看Http。然后它工作
答案 3 :(得分:0)
在开发环境(localhost)中,您可以轻松完成此操作,而无需执行任何困难的步骤。如果您使用的是firefox,则可以简单地下载https://addons.mozilla.org/firefox/addon/cors-everywhere/,并且我认为chrome也必须有扩展名。下载它会进入firefox菜单栏,然后单击它可以将其激活,这就是您现在可以访问所有api的全部内容,因为它会自动发送带有所有请求的标头。对于生产环境,您必须通过添加访问权限在服务器上对其进行配置-control-allow-origin到*(全部)