【问题标题】:CORS preflight request not handled by external API外部 API 未处理 CORS 预检请求
【发布时间】:2019-09-24 10:13:27
【问题描述】:

我正在尝试为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 端点,而无需任何飞行前请求。

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

【问题讨论】:

    标签: javascript api axios frontend


    【解决方案1】:

    CORS 预检请求是一个 CORS 请求,用于检查是否 理解 CORS 协议并且服务器知道使用特定的 方法和标头。

    有关预检请求的更多详细信息可以找到here.

    您可能应该研究如何在您的服务器上处理Content Security Policy。您从 javascript 发出的所有请求都将由浏览器验证。因此,您的服务器应使用标题 Access-Control-Allow-Origin 进行响应,了解有关 header here 的更多信息

    通过从浏览器网络选项卡进行检查,您应该能够查看响应中存在的标头。

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

    这里是一个示例 nginx vhost 配置,它处理具有 /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 标头,您应该明确提及域。

    【讨论】:

    • 感谢您的回答,詹姆斯!但这只是一般信息。您是在谈论将成为中间件的服务器吗?
    • @Justice47 首先你的服务器应该允许OPTIONS 请求。您能分享一下您的后端使用的框架吗?
    • 请再次阅读我的问题 - 我没有使用任何框架,我什至没有我的应用程序的任何后端部分。 API 受外部服务支持。
    • 首先您应该了解跨域请求的工作原理。如果您无法控制处理响应标头。您应该联系供应商。我在答案中提到的都是您遇到问题的原因。
    • 但是,您可以创建一个代理服务器,您可以完全控制它并通过它与提供者 API 进行通信。
    【解决方案2】:

    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')
    })
    

    【讨论】:

      猜你喜欢
      • 2014-10-31
      • 1970-01-01
      • 2019-08-29
      • 2016-02-17
      • 2020-11-18
      • 2012-11-17
      • 2016-02-16
      • 2014-08-16
      • 1970-01-01
      相关资源
      最近更新 更多