当我从Angular 8向外部API发送发布请求时,如何解决CORS错误?

时间:2020-02-05 20:18:54

标签: angular cors

我尝试向银行的API发送过帐请求,但出现此错误:

从源“ https://api_url”到“ https://client_url”处对XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:否'访问控制-Allow-Origin'标头出现在请求的资源上。

只要我自己不能在API中启用cors,是否有解决此问题的方法?

此应用程序位于MEAN堆栈中(Mongo-Express-Angular-Node)

2 个答案:

答案 0 :(得分:-1)

当没有对后端API的控制时,应该设法代理它,以便客户端URL和后端URL共享同一域。

根据您的情况,并取决于您的服务器环境,您可以:

  • 使Bank调用Express(http客户端,请求节点模块等)中的逻辑并将其公开为端点
  • 使用NodeJS完整的http代理(https://github.com/chimurai/http-proxy-middleware)来做到这一点:)
  • 使用轻量级的HTTP代理(通过Nginx,Httpd等)

所有三种选择都假定您的服务器环境可以访问Backend API

修改

在伪代码中,是这样的:

ExpressJS

app.get('/internal/bank/balance', function (req, res, next) {
  const balance = request('https://distantbank/api/balance')
  res.send(balance);
});

角度

const internalBankAPIUrl= '/internal/bank/';

getBalance() {
  return this.http.get(`${internalBankAPIUrl}/balance`);
}

答案 1 :(得分:-1)

以下是我的逻辑:

后端-NodeJS

app.js

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();

app.use(cors());
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb'}));
app.use(bodyParser.json({limit: '50mb'}));

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, *');
    if (req.method === 'OPTIONS'){
        res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, PATCH, DELETE, OPTIONS');
        res.setHeader('Access-Control-Allow-Credentials', true);
        return res.status(200).json({});
    }
    next();
});

const bankApi = require('./routes/bankApi');
app.use('/bank-endpoint', bankApi);

// Start the server

const port =  process.env.PORT || app.get('port') || 2020;
app.listen(port, () => console.log(`Server is listening on port ${port}`)); 

bankApi.js

const express = require('express');
const router = require('express-promise-router')();
const request = require('request');
const BankAPIURL = 'https://bankAPIURl.com'

const data = ''

router.get('/bank-endpoint', async (req, res) => {

await request(BankAPIURL, (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body)
    data = body 
    res.json({data});
  }
});

});  

前端-Angular8

数据-组件+ HTML

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';

@Component({
  selector: 'app-service',
  template: '{{bankData}}'
})
export class ServiceComponent implements OnInit {
  public apiBaseUrl: string = 'https://your-internal-domain-name';
  private bankData: any;
  private BankToken = 'this-is-my-secret-bank-auth-token';
  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  };

  jsonHeader = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json; charset=utf-8',
      Authorization: 'Bearer ' + this.BankToken
    })
  };

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http.get<any>(this.apiBaseUrl + '/bank-endpoint').subscribe(data => {
      this.bankData = data;
      console.log(this.bankData);
    });
  }
}

因此您可以在我的答案中看到,我构建了一个自定义服务器+ API,以便执行来自内部服务器的外部API请求。在app.js中,我包含了cors包来处理CORS请求。为了安全起见,我还设置了一对headers。然后,我在内部API查询外部银行的API的地方加载路由。然后,定义我的内部端点/bank-endpoint,当使用时,依次调用已经定义了CORS选项的外部端点。最后,我启动服务器。

接下来,在bankApi.js中,在这里定义我的内部API端点,该端点从银行调用外部api端点。取回数据后,我将其作为JSON返回,以便在Angular的前端使用。

在前端,我只是简单地创建了一个组件,该组件将调用API端点,并在HTML模板{{bankData}}中向用户显示结果。在更有条理的项目体系结构中,您将在Angular Service中定义对内部端点的HTTP调用,然后仅将该服务包含到组件中,然后调用将执行HTTP请求的服务。

我不保证此特定示例将起作用。我要做的就是给您一个radmap / logic / flow。 如果您还有其他问题需要回答,请与我们联系。