Python Flask CORS - 请求的资源上不存在“Access-Control-Allow-Origin”标头

Posted

技术标签:

【中文标题】Python Flask CORS - 请求的资源上不存在“Access-Control-Allow-Origin”标头【英文标题】:Python Flask CORS - No 'Access-Control-Allow-Origin' header is present on the requested resource 【发布时间】:2021-07-17 23:46:20 【问题描述】:

我在 Shopify 产品页面上编写了一个简单的 Ajax 脚本。每当单击上传按钮时,都会触发此脚本并向 API 服务器发送一条 json 消息

 jQuery.ajax(
            url: "https://e20e2287e2cb.ngrok.io/return_json",
            type: "POST",
            data: form_data,
            processData: false,
            contentType: false,
            contentType: "application/json",
            success: function (result) 
              var obj = jQuery.parseJSON( result );
                jQuery(".select-loader").remove(); 
                jQuery("body").removeClass('active-loader');
                jQuery("#upload_image").removeClass("err");
                jQuery("#upload_image").val("");
                jQuery("#google_folder_id").val(obj.imguniquename);
                jQuery("#customImage").val(obj.imgname);
                jQuery("#customImageUrl").val(obj.folder_id);
                jQuery("#customUniqueImage").val(obj.imguniquename);
                
                jQuery("#upload_image").after('<p class="note note--success">Image uploaded successfully.</p>');
                Cookies.set('google_folder_id', obj.imguniquename);
                Cookies.set('customImage', obj.imgname);
                Cookies.set('customImageUrl', obj.folder_id);
                Cookies.set('customUniqueImage', obj.imguniquename);

            
          );

在 API 服务器中,我有以下用 Python 编写的代码:

#Flask Library
from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
from flask_ngrok import run_with_ngrok

app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
logging.getLogger('flask_cors').level = logging.DEBUG
CORS(app)
run_with_ngrok(app) 

@app.route("/return_json", methods=["POST"])
def returnJson():
    return jsonify('folder_id':'yoyo', 'img':'adad', 'imgname':'bibi', 'imguniquename':'kaka')

if __name__ == '__main__':
    app.run()

谁能告诉我为什么每当触发 Ajax 脚本时我的浏览器控制台会出现以下错误?

    从源“https://www.abcabc.com”访问“https://e20e2287e2cb.ngrok.io/return_json”处的 XMLHttpRequest 已被 CORS 策略阻止:无“访问控制允许源”请求的资源上存在标头。 POST https://e20e2287e2cb.ngrok.io/return_json net::ERR_FAILED

同时,在 API 服务器端,调试日志对我来说看起来很好,如下所示:

调试: flask_cors.extension:对“/return_json”的请求与 CORS 资源“/”匹配。使用选项:'origins': ['.'], 'methods': 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT', 'allow_headers': ['.'] , 'expose_headers': None, 'supports_credentials': False, 'max_age': None, 'send_wildcard': False, 'automatic_options': True, 'vary_header': True, 'resources': '/', '拦截异常':真,'always_send':真

调试:flask_cors.core:CORS 请求收到'Origin'https://www.abcabc.com

DEBUG: flask_cors.core:请求的 Origin 标头匹配。发送 CORS 标头。

调试: flask_cors.core:Settings CORS 标头:MultiDict([('Access-Control-Allow-Origin', 'https://www.abcabc.com'), ('Vary ', '起源')]) 信息:werkzeug:127.0.0.1 - - [23/Apr/2021 11:04:44] “POST /return_json HTTP/1.1”200 -

【问题讨论】:

【参考方案1】:

由于我没有注意到您已经在使用 Flask-CORS,因此我正在通过进一步调查更新此答案。

我已经启动了一个测试环境,并设法使这个跨域请求正常工作,而无需更改您的代码。在此过程中,我想出了以下可能导致您出现问题的原因:

    确保请求现有的隧道端点。获取关闭的 NGROK 隧道端点会导致 CORS 错误,它不会引发 404。为了确保我请求的是正确的隧道,我编写了一个仅返回成功的索引视图路由。我还使用此端点来确保为所有 HTTP 方法(GET、POST...)正确设置了 CORS; 请务必导入日志记录,Flask 可以延迟评估应用程序并仅在请求时引发异常。查看您的控制台以获取回溯; 在 Flask 中,如果在请求期间发生异常,请求处理流程将被中止,并且永远不会调用 Flask-CORS 将其标头添加到响应对象中,并且您的浏览器将始终抱怨“Access-Control-Allow” -起源'。这就是为什么您应该始终检查浏览器的“响应选项卡”,它可能包含回溯或其他一些有用信息; 在访问 http://localhost:4040/ 的 NGROK introspect 中检查一些信息,它可能会帮助您跟踪许多问题; 我在运行通过 pip 提供的 flask-ngrok 时遇到了一些问题。我已经从 GitHub 下载了它的源代码并将其导入到我的演示应用程序中。坦率地说,我会放弃这个扩展,只在另一个控制台中运行 $ ngrok http 5000; 请务必设置 FLASK_DEBUG=true 否则它可能会对您隐藏一些信息/回溯。

查看此 Gist 以获取我使用的源代码和一些证据:https://gist.github.com/magnunleno/8dad91f133a22322250d6cb609792597

如果您发现任何新信息或追溯,请告诉我,以便我们制定解决方案。

旧答案

当您在特定域下运行服务器(在您的情况下为 e20e2287e2cb.ngrok.io)但您的 Web 客户端在不同域中运行(假设 www.abcabc.com)并且他们尝试通信时,就会发生这种情况。你真的应该看看this。

可以通过管理您的应用标头Access-Control-* 来配置此行为,幸运的是,有一个很好的扩展程序可以为您做到这一点,称为Flask-CORS。

【讨论】:

如果您查看我发布的代码,我已经按照flask-cors.readthedocs.io/en/latest 的说明导入并声明了flask_cors。此外,根据 API 服务器的调试日志,flask_cors 似乎已经使用 Access-Control-Allow-Origin 设置了响应标头 抱歉,没有注意到您已经在使用flask-cors。如果一切就绪,就不应该发生。我将设置一个类似的环境来检查这一点,但同时您是否在请求错误后检查了您的浏览器网络选项卡?什么是原始服务器响应?你的 shell 中是否有任何来自 Flask 的回溯? 嘿@BrianLo,为了清楚起见。在您的示例代码中,您使用的是logging,但没有import logging。你有没有机会忘记导入它?根据 Flask 的设置方式,它可以在启动期间忽略此类错误,仅在请求期间引发此类异常,并且由于请求被中止,因此未设置 CORS 标头。这是我在使用 CORS 时必须处理的一个常见问题... @MagunLeno logging 已经导入。我只是没有在这里发布我的所有代码。您可以在此处找到网络选项卡的屏幕截图:drive.google.com/file/d/19t6p-_vBbSmmVkPyY6TFKtPg-fiCanJp/… 嘿@BrianLo,我刚刚为您的问题构建了一个测试环境,一切正常。请检查我在原始答案中所做的更新。

以上是关于Python Flask CORS - 请求的资源上不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 请求的资源上没有“Access-Control-Allow-Origin”标头

Python Flask Cors 问题

[flask] flask api + vue 跨域问题

flask 跨域问题

flask_cors跨域请求

允许使用 Flask 和 React 请求 CORS