解决 axios 跨域时,发送 post 请求变 options 的问题

解决axios跨域时,发送post请求变options的问题

在使用vuejs开发前后端完全分离的项目时,都会使用跨域请求。在开发过程中就遇到这样的坑。直接上代码

let config = {
        headers : {
            'Content-Type':'application/json;charset=UTF-8'
        },
    };
axios.post(this.authUrl,JSON.stringify(this.userInfo),config)
    .then(res => {
        console.log(res)
    })
    .catch(err => {
         console.log(err)
    })

上面的代码在请求之后的结果如下

Request URL:http://59.110.160.110:9990/login

Request Method:OPTIONS

Status Code:404 Not Found

Remote Address:59.110.160.110:9990

Referrer Policy:no-referrer-when-downgrade
Response Headers

view source

Access-Control-Allow-Credentials:true

Access-Control-Allow-Headers:Content-Type, Content-Encoding, Cache-Control,

Content-Length, Accept-Encoding, Authorization, Origin, X-Requested-With,

Accept
Access-Control-Allow-Methods:GET, POST

Access-Control-Allow-Origin:*

Content-Length:18

Content-Type:text/plain

Date:Tue, 10 Oct 2017 08:58:57 GMT

Request Headers

view source

Accept:/

Accept-Encoding:gzip, deflate

Accept-Language:zh-CN,zh;q=0.8

Access-Control-Request-Headers:content-type

Access-Control-Request-Method:POST

Connection:keep-alive

Host:59.110.160.110:9990

Origin:http://localhost:8080

Referer:http://localhost:8080/

User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

上面的结果导致总是返回404 ,因为后台不允许options访问。

后来查询各种资料发现:根源在于,我们发出去的请求不是 simple request,那么在每次发送请求之前,都会发送一个options请求,simple request 需要同时满足以下条件(规范可以百度查询):

  1. get、post、head 请求类型
  2. 不要设置列表之外的header(如: user-agent)
  3. Content-Type 只能是:
    1. application/x-www-from-urlencoded
    2. multipart/from-data
    3. text/plain

其他资料也说过,默认请求就是application/json,所以不需要自己加上头部,现在上正确的代码:

axios.post(this.authUrl,JSON.stringify(this.userInfo))
    .then(res => {
        console.log(res)
    })
    .catch(err => {
        console.log(err)
    })

可以看到,我们没有上面的config的配置了。问题也就出在这里,OK问题解决

本帖已被设为精华帖!
本帖由系统于 2年前 自动加精
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 12
Epona

我一般是在API端使用laravel-cros,全局跨域,就不用管跨域问题了?

6年前 评论

@Epona 是的,后台做了设置之后,前段就可以了。但是axios的post会发送两次请求。导致请求的options请求失败,返回404,这个是解决这个404问题的,因为你后台允许的请求只是post,当你是options时肯定是找不到的。

6年前 评论

跨域直接使用laravel-cros中间件就行了
option是为了检测用的,服务器统一请求后才会发送下一个post,而不是变成option,这个是浏览器自动发送的
楼上MrJing的链接中讲的很详细,楼主可以研究下

6年前 评论
leo

楼主这种写法提交的 Content-Type 实际上应该是 application/x-www-from-urlencoded

6年前 评论

@MrJing 非常感谢,因为查过很多资料都不是很全,在这里发表一次,希望大家能一起帮助新人解决这些没见过的问题

6年前 评论

@leo 在浏览器抓包并没看到是什么类型,所以找了好多资料都没找出问题

6年前 评论
巴啦啦

很早以前碰到过,前端老说我这里有问题,后面我去它工位上调试,看请求信息才发现用axios请求时,这个包会先发一个探测请求,然后再发送客户端请求

6年前 评论

@仰望 最后就变成了options请求了

6年前 评论

跨域请求浏览器会先发送一个options试探请求,试探请求允许通过后才去发送post请求!

6年前 评论

我也是用barryvdh/laravel-cors,只对前端域名授信

6年前 评论

感谢大佬 , 搜了好久 , 很多人就一直解释这样问题那样问题 , 废话一堆, 就是不告诉我怎么解决 , 或者解决方法很复杂 .... 终于看到大佬这篇文章 ! 非常有用

3年前 评论
bean (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!