【问题标题】:Angular 7 app getting CORS error from angular clientAngular 7 应用程序从 Angular 客户端获取 CORS 错误
【发布时间】:2019-04-27 15:55:53
【问题描述】:

我开发了一个带有 express 后端的 angular 7 应用程序。 Express 在localhost:3000 上运行,Angular 客户端在 localhost:4200 上运行。

server.js我有(不是整个代码)

const app = express();
// Enable CORS
app.use(cors());
// Get our API routes
const api = require('./api');
// Set our api routes
app.use('/api', api);
app.use(express.static(__dirname + '/dist/sfdc-event'));

在 api.js 文件中,我有 router.get('/oauth2/login') 重定向到https://example.com,它发送访问令牌并对用户进行身份验证(OAuth2 身份验证)。

当我调用 url http://localhost:3000/api/oauth2/login 时,一切正常,但是当我尝试从 angular component.ts -> service.ts 执行相同操作时,我收到以下错误。

跨域请求被阻止:同源策略不允许读取 远程资源原因:CORS 标头“Access-Control-Allow-Origin” 不见了

Angular 应用流程如下 login.component.ts,其中有一个按钮调用服务 api.service.ts,该服务执行 http get。

login.component.ts

sfdcLogin(): void {
  console.log('DEBUG: LoginComponent: ', 'Login button clicked..');
 this.apiService.login().subscribe( data => { console.log( data ); });
}

api.service.ts

login() {
  console.log('DEBUG: APiService login(): ', 'login() function.');
  const URL = 'oauth2/login';
  console.log('DEBUG: ApiService login URL : ', `${environment.baseUrl}/${URL}`.toString());
  return this.http.get(`${environment.baseUrl}/${URL}`)
    .pipe( map( res => res ));
}

有人可以帮我解决这个错误吗?我有 a) CORS b) 从 server.js 提供静态文件作为

app.use(express.static(__dirname + '/dist/sfdc-event'));

c) 动态环境变量。 我还缺少什么?

【问题讨论】:

  • 响应的 HTTP 状态码是什么?
  • @Arup Sarkar,如果适用,请标记正确答案

标签: node.js angular express cors angular7


【解决方案1】:

如果这只是为了开发,我建议使用 angular-cli 附带的代理。 创建一个名为 proxy.json 的文件

{
  "/api/oauth2/login": {
    "target": "http://localhost:3000/api/oauth2/login",
    "secure": false
  }
}

和电话ng serve --proxy-config proxy.json。如果您认为这仍然是生产中的问题,那么我们必须进行更大的对话。

完整文档: https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md

还有什么是 CORS:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

【讨论】:

    【解决方案2】:

    对于 Angular 7,您必须进行其他实现。从 Angular 文档中,您必须创建一个 proxy.js 文件:

    https://angular.io/guide/build#using-corporate-proxy

    编辑您自己的后端服务器的路径。

    proxy.js:

    var HttpsProxyAgent = require('https-proxy-agent');
    var proxyConfig = [{
      context: '/api',
      target: 'http://your-remote-server.com:3000',
      secure: false
    }];
    
    function setupForCorporateProxy(proxyConfig) {
      var proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;
      if (proxyServer) {
        var agent = new HttpsProxyAgent(proxyServer);
        console.log('Using corporate proxy server: ' + proxyServer);
        proxyConfig.forEach(function(entry) {
          entry.agent = agent;
        });
      }
      return proxyConfig;
    }
    
    module.exports = setupForCorporateProxy(proxyConfig);
    

    稍后将其添加到您的 package.json 中

    "start": "ng serve --proxy-config proxy.js"
    

    然后调用它:

    npm start
    

    在您的 app.js 中只需简单地添加:

    const cors = require("cors");
    app.use(cors());
    

    我遇到了同样的问题,这解决了我的问题。希望对你有帮助!

    【讨论】:

      【解决方案3】:

      要将所有对http://localhost:4200/api 的调用转移到在http://localhost:3000/api 上运行的服务器,请执行following 步骤。

      1. 在项目src/ 文件夹中创建一个文件proxy.conf.json,在package.json 旁边。

      2. 将以下内容添加到新的代理文件中:

      {
          "/api": {
              "target": "`http://localhost:3000`",
              "secure": false
          }
      }
      
      1. 在 CLI 配置文件 angular.json 中,将 proxyConfig 选项添加到服务目标:
      ...
      "architect": {
          "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "options": {
                  "browserTarget": "your-application-name:build",
                  "proxyConfig": "src/proxy.conf.json"
              },
          ...
          }
      }
      ...
      
      1. 要使用此代理配置运行开发服务器,请致电 ng serve

      【讨论】:

      • 感谢您的解释。这就是我所做的,但我仍然对带有 Express.js 的 Angular 9 有问题 Access to XMLHttpRequest at 'localhost:7777/api/login' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
      • @DineshKumar 我不是这个答案的原始所有者,我只是将它编辑为具有清晰的代码格式,你应该问 TiyebM。无论如何,我想是的,但我没有尝试。
      • 您好,目标设置为"localhost:3000`"。那么在QA或PRODUCTION中,如何设置呢?我们只有一个代理文件。
      【解决方案4】:

      我一直在服务器端使用 Angular cli.net Framework

      为了解决这个问题,我只是使用以下步骤在服务器端启用 CORS 交互:

      1. Install-Package Microsoft.AspNet.WebApi.Cors -Version 5.2.6

        然后,进入 WebApiConfig 类:

      2. 添加using System.Web.Http.Cors;

      3. 内部注册(HttpConfiguration config)方法:

      var cors = new EnableCorsAttribute("http://localhost:4200", "*", "*");
      
      config.EnableCors(cors);
      

      var cors = new EnableCorsAttribute("*", "*", "*"); //origin, headers, methods
      
      config.EnableCors(cors);
      

      【讨论】:

        【解决方案5】:

        我更改了回调机制以解决 CORS 问题,我正在使用 OAuth 流程让用户从 https://example.com 进行身份验证,该流程重定向到 https://example.com/auth/callback,我从 http://localhost:4200 发起请求,然后将回调 url 发送到服务器 http://localhost:3000,我收到了 CORS 错误。

        现在,我将其重定向到客户端 http://localhost:4200 并解决了 CORS 问题。所有其他对 GET、POST、DELETE、PATCH 的调用都来自 http://localhost:3000,它工作正常。

        感谢大家的投入。

        【讨论】:

          【解决方案6】:

          默认情况下,Angular 会设置一些请求头参数,其中一个是“Content-Type”,其默认值为“application/json”。当我设置为“application/x-www-form-urlencoded”时,它为我解决了这个错误。

          而不是使用 post 方法,例如:

          this.http.post<any>(requestDetails['url'],requestDetails['data'])
          

          首先使用Angular的HttpHeaders类设置请求头,如:

          let reqHeaders = new HttpHeaders({
             'Content-Type':'application/x-www-form-urlencoded'
          });
          this.http.post<any>(requestDetails['url'],requestDetails['data'],{headers:reqHeaders})
          

          参考:https://angular.io/guide/http#adding-and-updating-headers

          在我的例子中,'Access-Control-Allow-Origin' 也设置为 * 用于服务器上的响应标头,以接受来自任何来源的请求(在开发案例中,它主要是:localhost:4200)

          【讨论】:

            【解决方案7】:

            我知道这已经得到解答,但它可能会对正在搜索 CORS 问题的人有所帮助。 您可以按照以下 3 个步骤来解决此问题。 1. 创建 proxy.conf.json 文件并将其放在应用程序的根级别。 2.在package.json文件中,在ngstart中添加proxy参数 3.在angular.json中,添加代理文件入口。 4. 将所有休息调用更改为 /api/getData 之类的内容。

            此处提供了完整的分步教程。 http://www.codeyourthought.com/angular/proxy-to-make-http-call-in-angular/

            【讨论】:

              【解决方案8】:

              由于您的 Angular 应用程序在 4200 端口上运行,而后端在 3000 端口上运行,因此这两个应用程序的来源是不同的。

              要解决这个问题,你可以在你的机器上设置“nginx”。

              这将使您从角度和后端发出的所有请求都通过“nginx”服务器进行。这样就解决了CORS的问题。

              【讨论】:

              • 最终,这将托管在 heroku PAAS 上。我不确定我是否可以使用“nginx”服务器。仅供参考,我已将应用程序上传到 heroku,这是相同的行为。
              • @ArupSarkar 我确定 heroku 中有一个 CORS 标头设置。阅读这篇文章 10 分钟,它解释了一切:developer.mozilla.org/en-US/docs/Web/HTTP/CORS
              猜你喜欢
              • 1970-01-01
              • 2019-08-05
              • 2019-01-09
              • 2014-03-26
              • 2018-10-26
              • 2019-12-09
              • 1970-01-01
              • 2021-01-04
              • 1970-01-01
              相关资源
              最近更新 更多