由于不允许的预检标头,Vue.js 前端与 Flask 后端交互出现 CORS 问题

TPP*_*PPZ 2 cors flask vue.js vue-resource

我在 Chrome 浏览器中遇到以下错误消息:

无法加载http://localhost:5000/my_endpoint:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段 Access-Control-Allow-Origin。

浏览器正在使用 webpack 等和vue-resource从 Vue.js 前端应用程序加载网页,以向 REST 后端执行 HTTP 请求。

URLhttp://localhost:5000/my_endpoint是由 python Flask 应用程序提供服务的 HTTP GET/POST 端点。

在前端 Javascript 上,我有这些 CORS 设置:

import VueResource from 'vue-resource'

Vue.use(VueResource)

Vue.http.options.crossOrigin = true
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'
Run Code Online (Sandbox Code Playgroud)

在 Flask 应用程序的后端 python 代码中,我有以下 CORS 配置详细信息:

@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Headers'] = 'Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization'
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS, HEAD'
    response.headers['Access-Control-Expose-Headers'] = '*'
    return response
Run Code Online (Sandbox Code Playgroud)

在 Javascript 前端执行此 HTTP POST 请求时:

this.$http.post("http://localhost:5000/my_endpoint", { my_custom_key: "my custom value"})//, {emulateJSON: true})
  .then((response) => {
    // do stuff
  })
Run Code Online (Sandbox Code Playgroud)

HTTP POST 请求的 JSON 正文在哪里{ my_custom_key: "my custom value"},然后由于某种原因在 Flask 后端我看到一个 HTTP OPTIONS 请求即将到来,参见 烧瓶日志:

127.0.0.1 - - [26/Jun/2018 21:45:53] "OPTIONS /ad HTTP/1.1" 200 -
Run Code Online (Sandbox Code Playgroud)

在能够从后端检索 JSON 数据之前,必须进行某种来回仪式,但我迷失在这些细节中。

在互联网上我看到了各种各样的解释,并且我一直在研究vue-resource配置细节,例如:

  • 添加/删除{emulateJSON: true}HTTP POST 请求
  • 添加/删除Vue.http.options.xhr = { withCredentials : true };Vue.js 的配置

但我无法检索来自后端的 JSON 数据。

在 Vue.js 文档或https://github.com/pagekit/vue-resource上搜索“CORS”并没有提供任何有关如何通过跨源资源共享 (CORS) 修复这些问题的信息。

如何让 Vue.js 前端与 Flask 后端一起处理这些 CORS 问题?

TPP*_*PPZ 5

解决方案是从前端删除:(Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'这实际上没有意义,因为它是通常进入后端响应的 HTTP 标头)。

另外,为了清理更多的后端,我发现这response.headers['Access-Control-Expose-Headers'] = '*'是不需要的。也许其他 HTTP 标头可以更精简,但现在我保持原样。