Vue生产应用跨域请求未发送OPTIONS预检致CORS报错
问题根因
你观察到的「后端宕机也报CORS错、没有OPTIONS请求发出」都是符合CORS规范的正常表现,不属于异常:
- 没有OPTIONS预检请求的原因:你当前的axios请求属于CORS定义的简单请求,浏览器默认不会发送OPTIONS预检。简单请求的判定规则为:
- 请求方法为
GET/HEAD/POST三者之一 - 手动设置的请求头仅包含
Accept、Accept-Language、Content-Language、Content-Type,且Content-Type取值仅限application/x-www-form-urlencoded、multipart/form-data、text/plain - 未在XMLHttpRequestUpload对象上绑定事件监听器,未使用ReadableStream传参
你当前仅开启了withCredentials标识,未添加任何自定义请求头,使用GET默认参数,完全符合简单请求标准,因此浏览器直接发送实际GET请求,不会触发预检。你访问YouTube时能看到OPTIONS请求,是因为对应请求添加了自定义头、或者使用了非简单请求的Content-Type(比如application/json),触发了预检逻辑。
- 请求方法为
- 后端宕机也报CORS错误的原因:CORS校验是浏览器对所有跨域响应的统一校验逻辑,和HTTP状态码无关。只要跨域响应没有携带符合要求的CORS头,不管是200成功响应还是502/503错误响应,浏览器都会拦截响应内容,抛出你看到的CORS错误。你提到ALB本身不处理CORS、仅透传请求,那后端宕机时ALB返回的默认错误页响应自然不会带CORS头,触发报错完全符合预期。
操作方案
强制触发OPTIONS预检的配置
如果确实需要让浏览器在发送实际请求前先发送OPTIONS预检,只需要让请求不符合简单请求规则即可,最通用的做法是添加一个自定义请求头,axios配置示例如下:
axios.get( "https://ALBURL", { withCredentials: true, headers: { "X-Requested-With": "XMLHttpRequest" } } )
添加该配置后,浏览器会自动判定请求为非简单请求,在发送GET请求前先发送OPTIONS预检请求。
注意:仅触发预检无法解决你的CORS报错问题,只要响应(包括OPTIONS预检响应、后端正常响应、后端宕机时ALB返回的错误响应)没有携带正确的CORS头,依然会抛出相同的错误。
彻底解决CORS报错的必要配置
由于你开启了withCredentials: true,需要在返回响应的所有链路(正常状态下的后端服务、后端宕机时返回错误响应的ALB层)配置以下响应头:
Access-Control-Allow-Origin:不能配置为通配符*,必须精确匹配你的前端源地址,即HTTPS://APIGATEWAYURLAccess-Control-Allow-Credentials: true- 对于OPTIONS预检请求,还需要额外返回:
Access-Control-Allow-Methods:需包含你实际使用的请求方法,比如GET, POST, OPTIONSAccess-Control-Allow-Headers:需包含你请求中携带的所有自定义头,比如上面示例添加的X-Requested-With
你可以先在ALB层配置固定响应规则,给所有状态码为5xx的默认错误响应加上上述CORS头,再给后端服务的所有响应(包括OPTIONS响应)加上对应头,即可解决问题,不需要使用代理方案。
内容的提问来源于stack exchange,提问作者dschon
相关产品推荐
相关产品推荐

