Angular 6 HttpClient - CORS问题

8

我的Nodejs restful服务有以下端点http://localhost:3000/api/countries。我正在使用这个中间件https://github.com/expressjs/cors。我启用了cors,因此:

const cors = require('cors');
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

我在位于 http://localhost:4200 的 Angular 6 应用程序中拥有以下代码。

   import { HttpClient, HttpHeaders } from '@angular/common/http';

   httpClient: HttpClient;

   getCountries(): Observable<any> {
     const url = 'http://localhost:3000/api/countries';
     const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin':'*'
      })
     };
     return this.httpClient.get(url, httpOptions).pipe(
        map((result: any) => {
            return result;
        })
     );
   }

我在我的React应用程序中有以下代码:http://localhost:3001

getCountries() {
    const url = 'http://localhost:3000/api/countries';
    const init = {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      }
   };

   try {
    const response = await fetch(url, init);
    const json = await response.json();
    return json
   };
 }

我的React代码完美地实现了所需的响应,但是Angular 6出现了以下错误:-
“Access to XMLHttpRequest at 'http://localhost:3000/api/countries' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.”
请问我的Angular 6代码有什么问题?
请注意,我已经看到类似问题的答案,建议使用json文件(proxy.conf.json)作为代理服务器或安装Chrome扩展程序。这些对我来说都不是选项。
感谢您提供的帮助。
3个回答

6
你可以使用这个,如果你想要一个快速的临时解决方案。
const url = 'https://cors-anywhere.herokuapp.com/http://localhost:3000/api/countries';

谢谢@westdabestdb,但我想要能够投入生产的东西。我猜我错过了什么,因为问题显然不在Restful服务上,因为另一个Web应用程序(React)可以成功调用它。 - Sola Oderinde
1
没有人希望“权宜之计”成为答案 :( ,感谢你的努力! - Carlos.V

2

CORS大多是后端问题。你可以在Node.js上使用以下代码解决:

var express = require('express');
var app = express();
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();
});

但如果您想在前端解决它,您可以在Angular中使用这种代码。将此代码放入proxy.conf.json中(但请注意,仅添加一个斜杠就足以使其无法工作):

{
  "/api/*": {            <-- you may change this for /api/country
      "target": "http://localhost:3000",
      "secure": false,
      "logLevel": "debug",
      "changeOrigin": true
  }
}

在 package.json 文件中,以下是需要注意的:

"scripts": {
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.conf.json",
    ...
}

在angular.json中添加代理配置:

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "options": {
    "browserTarget": "event:build",
    "proxyConfig": "proxy.conf.json"  <-- this line
  },...

使用npm start命令启动它。

在您的情况下,它应该可以正常工作,但在其他情况下(当然不是在生产环境中),我发现使用Chrome或Firefox的临时扩展程序更容易。您可以使用ChromeFirefox的扩展程序来解决问题。此外,由于某些限制,它可能无法在Chromium和Chrome Canary中使用。

另外,对于React,以下代码可能有所帮助:

const proxy = require("http-proxy-middleware");

module.exports = app => {
  app.use(
    "/api",   <-- here again, make sure it fits your needs or it won't work
    proxy({
      target: "http://localhost:3000",
      changeOrigin: true
    })
  );
};

后端这个对我来说是行的(这应该是正确的答案)。 - cfrostte

1
尝试使用 ng serve --port 3000。CORS 大多是后端问题。由于 React 在 localhost:3000 启动其服务器,因此您能够使用它,而 Angular 在 localhost:4200 启动,因此您遇到了跨域问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接