未由外部API处理的CORS飞行前请求

时间:2019-09-24 10:13:27

标签: javascript api axios frontend

我正在尝试为getresponse.com创建前端应用程序。它有自己的API,位于https://api.getresponse.com。当我尝试使用Axios或Fetch执行任何JavaScript请求表单浏览器时,出现此错误:

Access to XMLHttpRequest at 'https://api.getresponse.com/v3/accounts' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

在“网络”标签中,我有:

Request URL: https://api.getresponse.com/v3/accounts
Request Method: OPTIONS
Status Code: 400 Bad Request

据我所知,使用API​​无法正确处理来自网络浏览器的“复杂”请求。

现在我只有一个主意-制作一些中间件,该中间件可以将我的请求代理到API端点,而无需任何预检请求。

我是对的吗?我找不到这种中间件的任何示例。在哪里可以找到任何信息?

2 个答案:

答案 0 :(得分:3)

  

CORS预检请求是一种CORS请求,用于检查是否   了解CORS协议,并且服务器可以使用特定的   方法和标题。

有关预检请求的更多详细信息,请参见here.

您可能应该研究如何在服务器上处理Content Security Policy。对于您从javascript发出的所有请求,浏览器都会对其进行验证。因此,您的服务器应以标头Access-Control-Allow-Origin作为响应,以详细了解header here

通过从浏览器的“网络”标签中进行检查,您应该能够查看响应中显示的标题。

由于您无法控制API服务器,因此可以创建一个proxy server与外部服务器进行通信。您可以找到详细的tutorial here

以下是一个示例nginx虚拟主机配置,该配置处理所有具有/apihttps://api.example.com的请求的代理

server {
  listen 80;
  server_name example.com;   # Your server domain, in your case localhost
    location /api {
      access_log off;
      proxy_pass https://api.example.com;  # <--- this will the target domain
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

因此,如果您创建http://example.com/api/v3/accounts,它将被转发到https://api.example.com/api/v3/accounts

基本上,您的回复中应包含以下标头。

Access-Control-Allow-Origin: https://yourdomain.com

您还可以具有以下配置。

Access-Control-Allow-Origin: *

如果您使用withCredentials,那么您不能在*标头中使用通配符Access-Control-Allow-Origin,则应明确提及域。

答案 1 :(得分:0)

James的回答是可以的,但是现在我更喜欢基于Node.js而不是Nginx的解决方案,因为我是在Windows上本地开发的。 我想到了Express服务器的解决方案:

var cors = require('cors')
var app = express()
var proxy = require('express-http-proxy'); 

app.use(cors())

app.use('/', proxy('https://api.getresponse.com'))

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})