使用 vue.js 的 axios 预检失败错误 301

Posted

技术标签:

【中文标题】使用 vue.js 的 axios 预检失败错误 301【英文标题】:axios preflight fail error 301 using vue.js 【发布时间】:2017-12-14 07:05:50 【问题描述】:

我有一个 Laravel 5.4 API,它在 Postman 和浏览器中运行良好。 Localhost 运行良好——Laravel 5.4 在一个端口上运行,而 Vue 在热部署模式下运行良好。

但是,当我将 Vue 代码移动到我的生产服务器时,我收到了这个错误:

Response for preflight is invalid (redirect)

在 Chrome 开发者工具中,网络标签显示如下:

常规

Request URL:http://backend-dev.xolas.io/api/v1/view/calendar/-30/90/
Request Method:OPTIONS
Status Code:301 Moved Permanently
Remote Address:217.182.66.247:80
Referrer Policy:no-referrer-when-downgrade

响应标头

Connection:Keep-Alive
Content-Length:349
Content-Type:text/html; charset=iso-8859-1
Date:Mon, 10 Jul 2017 13:40:08 GMT
Keep-Alive:timeout=5, max=100
Location:http://backend-dev.xolas.io/api/v1/view/calendar/-30/90
Server:Apache/2.4.25 (Ubuntu)

原始标头

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:access-control-allow-origin,authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:backend-dev.xolas.io
Origin:http://localhost:8080
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Linux; android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Mobile Safari/537.36

我在 Laravel 上安装了一个 CORS 插件,还是不爽。

我的axios配置如下:

axios.defaults.headers.common['Authorization'] = store.apiKey
axios.defaults.headers.get['Content-Type'] = 'application/json;charset=utf-8'
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8'
axios.defaults.headers.common['Access-Control-Allow-Origin'] = 'https://' + store.endpoint + ', http://' + store.endpoint

Endpoint 是 Larvel API 服务器,工作正常。

任何线索都会有所帮助,因为我不知道如何解决这个问题。提前致谢。

【问题讨论】:

【参考方案1】:

在尝试任何请求之前,您的浏览器会发送 CORS preflight OPTIONS request,而您的代码实际上正在尝试发送自己,然后您的 Laravel 后端会使用 301 Moved Permanently 重定向响应该 OPTIONS 请求。

服务器必须以 2xx 状态响应 OPTIONS 预检 - 通常为 200 或 204。

如果服务器不这样做,预检将失败,浏览器永远不会尝试实际请求。

因此,您必须更改您的 Laravel 后端以使用 200 或 204 响应 OPTIONS

并且浏览器首先会进行预检,因为您的请求会添加 AuthorizationContent-Type: application/json;charset=utf-8Access-Control-Allow-Origin 标头。

您应该删除在那里添加 Access-Control-Allow-Origin 的代码,因为这是一个 response 标头,并且永远不需要在请求中发送它。但是假设您需要请求中的 AuthorizationContent-Type 标头才能使其在后端按预期实际工作,那么您无法避免浏览器预检。

所以你真的必须配置你的 Laravel 后端来响应OPTIONS 2xx 成功。

【讨论】:

谢谢@sideshowbarker。我理解你所说的大部分内容,我如何告诉 Laravel 以 200 响应响应?这是基于 axios 标头信息,还是基于 Laravel 端的配置?感谢您的回复。 如果你按照@MarkM 所指出的从请求 URL 中删除尾部斜杠然后找出并修复导致后端 500 失败的任何原因,那么我假设在这些更正之后你会获得 OPTIONS 请求的 2xx 响应,除了您已经配置的内容之外,您无需为 OPTIONS 添加任何额外的特殊处理【参考方案2】:

服务器正在从以下地址发送重定向:

http://backend-dev.xolas.io/api/v1/view/calendar/-30/90/

到:

http://backend-dev.xolas.io/api/v1/view/calendar/-30/90

删除请求中的尾随“/”应该可以防止 301。(尽管该 url 以 500 服务器错误响应。

【讨论】:

感谢@MarKM 成功了,但为什么要 x 2? 1) 在 Laravel 和 Vue 具有不同端口的本地主机上,它可以工作,而在生产端,它会失败 2) 为什么尾随的 '/' 会导致问题?这不是 URL 的正确格式吗?顺便说一句,-30/90 是 API 基本 URL 的参数。 这取决于服务器的设置方式。我不知道是否在任何规范中解决了尾斜杠/无尾斜杠问题。重要的是 /-30/90//-30/90 实际上是两个不同的 URL。服务器设置为通过转发到另一个来响应一个。它使用301 redirect 执行此操作。您可以设置服务器以向两者提供内容,但只需为其提供预期的 URL 工作量就会减少。也许本地服务器和产品服务器在这方面表现不同。使用curl -I http://backend-dev.xolas.io/api/v1/view/calendar/-30/90/ 很容易调查 感谢@MarkM,这很有道理。 我搜索了很长时间才发现一个错误,就是这样,哇.. 谢谢,为我工作。

以上是关于使用 vue.js 的 axios 预检失败错误 301的主要内容,如果未能解决你的问题,请参考以下文章

Azure APIM 在预检和从 axios 发出的 GET 请求时返回空响应正文,状态代码为 200

Axios CORS/Preflight 因 Laravel 5.4 API 调用而失败

Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败

在vue中使用axios的Cors和预检错误

在 vue 中使用 axios 的 Cors 和预检错误

Laravel Axios 使用 Vue 失败,状态码 419