尽管有效的CORS配置,“在飞行前响应中Access-Control-Allow-Headers不允许请求标头字段Access-Control-Allow-Origin" [英] “Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response” despite valid CORS config

查看:370
本文介绍了尽管有效的CORS配置,“在飞行前响应中Access-Control-Allow-Headers不允许请求标头字段Access-Control-Allow-Origin"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Google Cloud Functions创建了一个API端点,并试图从JS提取函数中调用它.

I created an API endpoint using Google Cloud Functions and am trying to call it from a JS fetch function.

我肯定会遇到与CORS或输出格式有关的错误,但是我不确定到底发生了什么.其他一些类似的问题,也使我意识到我需要删除 mode:"no-cors" .大多数人提到在BE上启用CORS,所以我添加了 response.headers.set('Access-Control-Allow-Origin','*')-我在

I am running into errors that I am pretty sure are related to either CORS or the output format, but I'm not really sure what is going on. A few other SO questions are similar, and helped me realize I needed to remove the mode: "no-cors". Most mention enabling CORS on the BE, so I added response.headers.set('Access-Control-Allow-Origin', '*') - which I learned of in this article - to ensure CORS would be enabled... But I still get the "Failed to fetch" error.

完整错误(在下面的实时演示中可以复制):

The Full Errors (reproducible in the live demo linked below) are:

未捕获的错误:无法添加节点1,因为具有该ID的节点是已经在商店中.( 这可能与之无关? )

访问地址为'https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5'来自来源"https://o2gxx.csb.app"的信息已被CORS政策阻止:请求标头字段的access-control-allow-origin不允许飞行前响应中的Access-Control-Allow-Header.

Access to fetch at 'https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5' from origin 'https://o2gxx.csb.app' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

获取 https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5 net :: ERR_FAILED

GET https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=37.75&lon=-122.5 net::ERR_FAILED

未捕获(承诺)TypeError:无法获取

Uncaught (in promise) TypeError: Failed to fetch

请参阅下面的代码段,请注意我使用< -------- ***消息*** 来表示最近更改的部分代码,这是我提供的两个代码之一错误.

See Code Snippets below, please note where I used <---- *** Message *** to denote parts of the code that have recently changed, giving me one of those two errors.

前端代码:

function getCSC() {
  let lat = 37.75;
  let lng = -122.5;

  fetch(
    `https://us-central1-stargazr-ncc-2893.cloudfunctions.net/nearest_csc?lat=${lat}&lon=${lng}`,
    {
      method: "GET",
      // mode: "no-cors", <---- **Uncommenting this predictably gets rid of CORS error but returns a Opaque object which seems to have no data**
      headers: {
        // Accept: "application/json", <---- **Originally BE returned stringified json. Not sure if I should be returning it as something else or if this is still needed**
        Origin: "https://lget3.csb.app",
        "Access-Control-Allow-Origin": "*"
      }
    }
  )
  .then(response => {
      console.log(response);
      console.log(response.json());
    });
}

后端代码:

import json
import math
import os
import flask

def nearest_csc(request):
    """
    args: request object w/ args for lat/lon
    returns: String, either with json representation of nearest site information or an error message
    """

    lat = request.args.get('lat', type = float)
    lon = request.args.get('lon', type = float)

    # Get list of all csc site locations
    with open(file_path, 'r') as f:
        data = json.load(f)
        nearby_csc = []

        # Removed from snippet for clarity:
        #    populate nearby_csc (list) with sites (dictionaries) as elems
        #    Determine which site is the closest, assigned to var 'closest_site'              

        # Grab site url and return site data if within 100 km
        if dist_km < 100:
            closest_site['dist_km'] = dist_km
            
            // return json.dumps(closest_site) <--- **Original return statement. Added 4 lines below in an attempt to get CORS set up, but did not seem to work**

            response = flask.jsonify(closest_site)
            response.headers.set('Access-Control-Allow-Origin', '*')
            response.headers.set('Access-Control-Allow-Methods', 'GET, POST')
            return response

        return "No sites found within 100 km"

以上代码段的完整上下文:

Fuller context for code snippets above:

  • Here is a Code Sandbox Demo of the above.
  • Here is the full BE code on GitHub, minus the most recent attempt at adding CORS.
  • The API endpoint.

我还想知道CodeSandbox是否有可能以一种奇怪的方式执行CORS,但是在 localhost:3000 上运行它时也遇到了同样的问题,当然在prod中会在我的产品上使用它自己的个人领域.

I'm also wondering if it's possible that CodeSandbox does CORS in a weird way, but have had the same issue running it on localhost:3000, and of course in prod would have this on my own personal domain.

错误似乎与CORS相关('https://o2gxx.csb.app'已被CORS策略阻止:Access-不允许请求标头字段access-control-allow-origin飞行前响应中的Control-Allow-Headers.),但我认为添加 response.headers.set('Access-Control-Allow-Origin','*')可以解决该问题.我需要在BE上进行其他更改吗?在FE上?

The Error would appear to be CORS-related ( 'https://o2gxx.csb.app' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.) but I thought adding response.headers.set('Access-Control-Allow-Origin', '*') would solve that. Do I need to change something else on the BE? On the FE?

TLDR;

我收到错误消息无法提取".且访问控制允许标题"不允许字段访问控制允许起源".即使尝试在后端启用CORS并将头添加到FE.请参阅上面的链接以获取实时代码演示.

I am getting the Errors "Failed to fetch" and "field access-control-allow-origin is not allowed by Access-Control-Allow-Headers" even after attempts to enable CORS on backend and add headers to FE. See the links above for live demo of code.

推荐答案

删除前端代码中添加 Access-Control-Allow-Origin 请求标头的部分.

Drop the part of your frontend code that adds a Access-Control-Allow-Origin request header.

切勿在前端JavaScript代码中添加 Access-Control-Allow-Origin 作为请求标头.

Never add Access-Control-Allow-Origin as a request header in your frontend JavaScript code.

唯一会产生的负面影响是,即使实际( GET POST 等),否则将不会触发预检.然后预检将失败,并显示以下消息:

The only effect that’ll ever have is a negative one, in that it’ll cause browsers to do CORS preflight OPTIONS requests even in cases when the actual (GET, POST, etc.) request from your frontend code would otherwise not trigger a preflight. And then the preflight will fail with this message:

在飞行前响应中,Access-Control-Allow-Headers不允许请求标头字段Access-Control-Allow-Origin

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response

…,否则将失败,除非已将发出请求的服务器配置为发送 Access-Control-Allow-Headers:Access-Control-Allow-Origin 响应标头.

…that is, it’ll fail with that unless the server the request is being made to has been configured to send an Access-Control-Allow-Headers: Access-Control-Allow-Origin response header.

但是您永远不需要 Access-Control-Allow-Headers 响应标头值中的 Access-Control-Allow-Origin .如果最终使一切正常,那实际上是在解决错误的问题.因为真正的解决方法是:永远不要将 Access-Control-Allow-Origin 设置为请求标头.

But you never want Access-Control-Allow-Origin in the Access-Control-Allow-Headers response-header value. If that ends up making things work, you’re actually just fixing the wrong problem. Because the real fix is: never set Access-Control-Allow-Origin as a request header.

直觉上,将其视为似乎合乎逻辑.我在请求和响应中都设置了 Access-Control-Allow-Origin ,因此应该比仅在响应中添加更好".但是实际上比在响应中设置它要糟糕(由于上述原因).

Intuitively, it may seem logical to maybe look at it as "I’ve set Access-Control-Allow-Origin both in the request and in the response, so that should be better than just having it in the response" — but it’s actually worse than only setting it in the response (for the reasons described above).

因此,最重要的是: Access-Control-Allow-Origin 仅是响应标头,而不是请求标头.因此,您只想在服务器端响应代码中进行设置,而不是在前端JavaScript代码中进行设置.

So the bottom line: Access-Control-Allow-Origin is solely a response header, not a request header. So you only ever want to set it in server-side response code, not frontend JavaScript code.

问题中的代码还试图添加 Origin 标头.您也永远不想尝试在前端JavaScript代码中设置该标头.

The code in the question was also trying to add an Origin header. You also never want to try to set that header in your frontend JavaScript code.

Access-Control-Allow-Origin 标头不同, Origin 实际上是一个请求标头-但它是一个特殊的标头,完全由浏览器控制,并且浏览器永远不会允许您的前端JavaScript代码进行设置.所以永远不要尝试.

Unlike the case with the Access-Control-Allow-Origin header, Origin is actually a request header — but it’s a special header that’s controlled completely by browsers, and browsers won’t ever allow your frontend JavaScript code to set it. So don’t ever try to.

这篇关于尽管有效的CORS配置,“在飞行前响应中Access-Control-Allow-Headers不允许请求标头字段Access-Control-Allow-Origin"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆