欢迎!从2017年开始,将慢慢的不在xmind上写总结了,全部转到博客中!这里将不再随便写写,将继承在xmind的精神,继续前行!!!

番外篇:axios相关 以及axios调用数据后台接收不到参数引发的 Request Payload 和formData 学习

前言

当接触并使用axios调用数据成功后,一般不会去研究axios与之前的ajax 有啥区别吧!公司用过程处理的数据,用ajax能顺利调用,但是换成axios就不成立,一番探究,发现确实有盲区!!

 

简介

大体区分 什么是FormData?什么是RequestPayload?直接通过图例说明

Request Payload更准确的说是http request的payload body。一般用在数据通过POST请求或者PUT请求。它是HTTP请求中空行的后面那部分。

一个请求伴随着header设置为Content-Type: application/json时候,看起来可能像这样:

POST /some-path HTTP/1.1
Content-Type: application/json

{ "foo" : "bar", "name" : "John" }

 

如果你正常请求一个ajax。浏览器会简单的将你提交的内容作为payload展示出来,这就是它所能做的,因为它不知道数据来自哪里。

如果你提交了一个html表单并且配置上了method="post",并且设置了Content-Type: application/x-www-form-urlencoded或者Content-Type: multipart/form-data。那么你的请求可能长这个样:

POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar&name=John

 

所以区别就是,他们只是因为Content-Type设置的不同,并不是数据提交方式的不同,这两种提交都会将数据放在message-body中。但是chrome浏览器的开发者工具会根据这个ContentType区分显示方式。

 

传统的Form表单提交

场景构造

<form action="/" method="POST">
    <input name="name" type="text">
    <input name="password" type="text">
    <button>提交</button>
</form>

点击提交,就会触发浏览器的提交功能,请求形式如下

clipboard.png

注意点

可以看到Content-Typeapplication/x-www-form-urlencoded
值得形式是以key1=value1&key2=value2的形式提交的。

传统的ajax提交

场景构造

function submit2() {
    var xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    var obj = {a: 1, b: 2};
    xhr.open('POST', '/');
    xhr.send(obj);
}

首先我们构造一个简单的函数,然后触发它。通过chrome反馈来看:

传统ajax提交

注意点

1.默认的Content-Typetext/plain
2.Request Payload会对非字符串做字符串转换。
3.通过xhr.send(JSON.stringify(obj));可修正要发的内容

axios方式提交

场景构造

由于axios已经是vue、react的准标配请求方式了,所以这里探究一下它。
首先我门看axios的文档,当post提交时候可以传递什么类型参数:

clipboard.png

注意这个类型,我们分别构造两个场景。对应它。

function submit3() {
    var sence1 = 'name=123&val=456';
    var sence2 = {name: 123, val: 456};
    axios.post('/', sence1)
}

分别传递字符串与对象,提交post请求,然后观察结果:

场景1——传递字符串时候的结果:
字符串提交场景

场景2——传递对象的结果:
对象提交场景

注意点

1.当我们传递字符串的时候,Content-Type自动转为xxx-form-xxx的形式。当为对象的时候,自动转化为xxx/json
2.字符串的时候以key1=val1&key2=val2的形式体现,对象以JSON字符串形式体现。

Content-Type的差异

1.传统的ajax请求时候,Content-Type默认为"文本"类型。
2.传统的form提交的时候,Content-Type默认为"Form"类型。
3.axios传递字符串的时候,Content-Type默认为"Form"类型。
4.axios传递对象的时候,Content-Type默认为"JSON"类型

解决方式 axios 参数为payload的解决方法

axios默认的格式是Request Payload

而如果后台使用Httpservlet时使用request.getParameter时只能拿到格式为formData的数据,这是就需要进行数据转换。

1. 添加头部headers

axios 设置 axios的headers设置放在了axios的构造中才设置成功.

axios.post('http://localhost:3000/api/goods/get',qs.stringify(data),{
        headers: {
            'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
          }
      }).then(res=>{
        _this.msg = res.data
      },err =>{
        console.log(err)
      })
 

 

2. 在Browser环境下

 2.1 利用qs.stringify()处理参数

var qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 });
复制代码
<script src="/your-path/qs.min.js"></script>
axios({
   url: url,
   method: 'post',
   data: Qs.stringify(params)   
})
.then(function (resp) {
//
})
.catch(function (err) {
//       
})
 
复制代码

2.2 利用 URLSearchParams API 处理post参数

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

查看 URLSearchParams 兼容性,还可以使用pollify

 3. 在node环境下

可以使用querystring 模块

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

或者使用qs.stringify(),qs同样可以在node中使用

 

2020.1.14补充  

 security只能接收form提交,由于我用的axios,所以需要模拟form提交

//方式
headers: {
           'Content-Type': 'application/x-www-form-urlencoded' 
}

//以及data格式需要转换一下

transformRequest: [function (data) {
      let ret = ''
      for (let it in data) {
        ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
      }
      return ret
    }],

 

 

参考 https://segmentfault.com/a/1190000018774494

 

2020-2-14  vue项目使用axios发送请求让ajax请求头部携带cookie的方法

vue项目时遇到登录权限问题,开始有个登陆的服务,返回cookie,以后的所有请求头部需要携带这个cookie,否则所有服务被拒绝访问。

axios官网的 说明

// `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // 默认的

简单方法:

import axios from 'axios'
axios.defaults.withCredentials=true;//让ajax携带cookie
Vue.prototype.$axios = axios;

OR
const service = axios.create({
   withCredentials:true,
})

接下来 遇到新的问题

虽然开启了携带cookie,但是在项目的域名中没有看到 相应的cookie,如图所示

 

百度寻找到的观点汇总

说法一:使用mockjs,他会劫持cookie,通过给mockjs配置withCredentials 参数即可携带cookie:
import Mock from 'mockjs';
Mock.XHR.prototype.withCredentials = true;

简评:这个说法我没事有去实践,直接关闭了mockjs,本来用的也不多

 

说法二:前端请求的域名和cookie的域相同吗 不相同的话 是不会自动带cookie的,

简评:这个说法得到解决,正如上图,刚开始两个域名不相同,我在localhost下就是看不到所要的cookie,当在浏览器中单独打开接口服务的域名就能看到,后来,后台同志一番操作,我在localhost下看到了 接口服务的cookie,实现了携带多个域名的cookie。

 

 

666

posted @ 2019-11-29 17:20  拐进web的奋斗者  阅读(2048)  评论(0编辑  收藏  举报