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

问题描述

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

const regex = /<([^<>]*[dD]ate[^<>]*)>\d{13}<\/\1>/;
[
  "<dateCreated>1619155581543</dateCreated>","<dispatchDate>1619478000000</dispatchDate>","<deliveryDate>1619564400000</deliveryDate>","<thirteendigits>1619564400000</thirteendigits>",].forEach(str => {
  const match = str.match(regex);
  console.log(match ? `Match --> ${str}` : `No match --> ${str}`)
});

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

 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);

            }
          });

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

  1. 从源“https://www.abcabc.com”访问“https://e20e2287e2cb.ngrok.io/return_json”处的 XMLHttpRequest 已被 CORS 政策阻止:无“访问控制允许源”请求的资源上存在标头。
  2. 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': 无,'supports_credentials': False,'max_age': 无,'send_wildcard': False,'automatic_options': True,'vary_header': True,'resources': '/','拦截异常':真,'always_send':真}

DEBUG: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 -

解决方法

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

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

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

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

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

旧答案

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

可以通过管理您的应用标头 Access-Control-* 来配置此行为,幸运的是,有一个很好的扩展程序可以为您执行此操作,名为 Flask-CORS

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...