只有在回调/异步函数内部时,Axios 请求才会收到 CORS 错误
Posted
技术标签:
【中文标题】只有在回调/异步函数内部时,Axios 请求才会收到 CORS 错误【英文标题】:Axios request receiving a CORS error only when inside a callback/async function 【发布时间】:2019-08-22 04:10:05 【问题描述】:我正在将 VueJS 用于我正在构建的应用程序。我拥有的服务器是用 Golang 编写的,并且已设置为接受 CORS。在应用程序中,在我的一个组件searchBar
中,我已将其设置为在创建之前获取一些数据。
var searchBar =
prop: [...],
data: function()
return ... ;
,
beforeCreate: function()
var searchBar = this;
axios.request(
url: '/graphql',
method: 'post',
data:
'query': 'coursesid, name'
)
.then(function(response)
searchBar.courses = response.data.data.courses;
);
,
methods: ... ,
template: `...`
;
Axios 在这里完美运行。它得到我需要的数据。 searchBar
有一个按钮,它会导致它发出一个事件,然后由另一个组件searchResults
拾取。收到事件后,searchResults
将获取一些数据。
var searchResults =
data: function()
return ...
,
mounted: function()
var sr = this;
this.$bus.$on('poll-server', function(payload)
var requestData =
url: '/graphql',
method: 'post',
data: ... ,
...
;
...
axios.request(requestData)
.then(function(response)
console.log(response);
);
);
,
template: `...`
;
请注意,我的 Axios 请求调用现在位于回调函数中。执行此调用时,我收到一个 CORS 错误:
从源“http://127.0.0.1:8080”访问“http://127.0.0.1:9000/graphql”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。
我的服务器位于http://127.0.0.1:9000
,客户端位于http://127.0.0.1:8080
。这是第二次请求调用的OPTIONS
请求的内容。
为了比较,这里是第一个请求调用的请求标头(有效!)。
我已经将我的 Golang 服务器设置为通过 go-chi/cors
支持 CORS。就是这样设置的。
router := chi.NewRouter()
...
// Enable CORS.
cors := cors.New(cors.Options
AllowedOrigins: []string"*",
AllowedMethods: []string"POST", "OPTIONS",
AllowedHeaders: []string"Accept", "Authorization", "Content-Type", "X-CSRF-Token",
ExposedHeaders: []string"Link",
AllowCredentials: true,
MaxAge: 300,
)
router.Use(
render.SetContentType(render.ContentTypeJSON),
middleware.Logger,
middleware.DefaultCompress,
middleware.StripSlashes,
middleware.Recoverer,
cors.Handler,
)
router.Post("/graphql", gqlServer.GraphQL())
return router, db
是什么导致了我遇到的错误以及如何解决?
【问题讨论】:
不熟悉 go-chi/cors,但您确定 CORS 设置正确吗?您的第一个 POST 请求很可能是正确的,但对于第二个 GET 请求却不是。该错误清楚地显示第二个 API 上没有 Allowed Origin 标头。 @colminator 我不小心留下了第二个请求的详细信息。第二个请求也是POST
请求。
请检查发送到服务器的OPTIONS
请求和响应,如果可以,请在此处发布
@BenYaakobi,我已将OPTIONS
请求添加到问题中。
@RejoanulAlam,是的,对于本地测试,不需要安全性。但是,最好将 dev/local 与生产中的内容相匹配。
【参考方案1】:
预计会出现此 CORS 错误。您使用的 CORS 插件会为您请求过滤。如果您查看允许的标头列表,您会发现它缺少您尝试在 axios 调用中发送的名为 snb-user-gps-location
的标头。
要么将该标头添加到允许列表中,要么不从前端发送。
【讨论】:
哇!我不认为我的自定义标题丢失导致了我的问题。我已经确认这确实是解决方法。非常感谢! 它还显示了发布与您的问题相关的所有代码的重要性,如果我没有查看您的请求的第一个屏幕截图,我永远不会发现这是您的错误,因为该屏幕截图是唯一提到此标题的地方【参考方案2】:我仍然怀疑 go-chi CORS 设置。我建议您手动设置 CORS。这并不难。此页面将获得基本设置:https://flaviocopes.com/golang-enable-cors/
如果这适用于您的嵌套 API 设置,那么我们可以向后确定 go-chi 配置问题。
更新:
我还将调查其他中间件步骤 - 注释掉所有非必要的步骤。
中间件处理程序通常检查r *http.Request
或将标头写入w http.ResponseWriter
,然后最终处理程序将写入响应正文。但是在整个中间件链中,以下标头/正文写入流程应该看起来像这两个流程之一:
成功:
w.Header().Set(...) // headers
w.Write(...) // body
请注意,上述流程将发出隐式的 http 状态代码写入,以保持标题出现 first 和正文 second:
w.Header().Set(...) // headers
w.WriteHeader(http.StatusOK) // implicit success http status code
w.Write(...) // body
失败:
如果报告运行时错误,流程应该是:
w.Header().Set(...) // headers
w.WriteHeader(http.StatusInternalServerError) // some unrecoverable error
w.Write(...) // optional body
之所以提出这个问题,是因为我看到了 3 种类型的错误,这些错误会扰乱这个流程:
错误的中间件处理程序在正文之后写入标头导致客户端混淆 调用http.Error
认为会停止 API 死机 - 而不是在 http.Error
之后立即返回并且确保不会调用后续中间件处理程序
两次写入相同的标头。在后续处理程序中重写标头将导致客户端看到最后一个版本(从而破坏任何以前的版本)
因此,为了全面追踪事情,我会 log.Println
为您的 API 写入所有标头/正文,以确保上述流程正确且没有预期值被覆盖。
【讨论】:
双 API?我一定把你弄糊涂了。我道歉。这些请求正在调用同一个 API。 我理解你的代码。在你调用它两次的意义上加倍。 哦。我知道了。我认为双重 API 设置具有误导性。无论如何,也许手动设置它是可行的。 最后一个想法:在(2nd)API调用的处理程序中是否有任何可能的http错误报告?如果是这样,从 header-writes 乱写错误代码可能会导致 headers(在这种情况下为 Origin)永远不会被发送。 显然,我的问题是由于我的自定义标头未包含在允许的标头中。 Ferrybig here 指出并解决了这个问题。不过,感谢您的努力。以上是关于只有在回调/异步函数内部时,Axios 请求才会收到 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章
在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]
在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]