论开发文档的重要性

959 阅读2分钟

前后台交互传参格式一定要协商统一

工作中遇到的一个问题

后台同事没有说清楚接口文档,导致用axios向后台传递的参数格式写了对象格式.其实后台想要的是x-www-form-urlencoded格式(类似于a=1&b=2).

报错信息

Access to XMLHttpRequest at 'http://test.xxx.com/XXX.asmx/XXX' from origin 'http://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

最神奇的就是这个报错信息,让我觉得是CORS哪里配置错误了,类似跨域问题.(现在想想确实是后台的配置限制了)

网络上的截图

Solution On Internet
Solution On Internet

解决

qs处理url参数

qs.parse 方法可以把一段格式化的字符串转换为对象格式

let url = 'http://item.taobao.com/item.html?a=1&b=2&c=&d=xxx&e';
let data = qs.parse(url.split('?')[1]);

// data的结果是
{
    a: 1, 
    b: 2, 
    c: '', 
    d: xxx, 
    e: ''
}

qs.stringify 则和 qs.parse 相反,是把一个参数对象格式化为一个字符串。

let params = { c: 'b', a: 'd' };

qs.stringify(params);

// 结果是
'c=b&a=d'

甚至可以对格式化后的参数进行排序:

qs.stringify(params, (a,b) => a.localeCompare(b));

// 结果是
'a=b&c=d'

指定数组编码格式

let params = [1, 2, 3];

// indices(默认)
qs.stringify({a: params}, {
    arrayFormat: 'indices'
})
// 结果是
'a[0]=1&a[1]=2&a[2]=3'

// brackets 
qs.stringify({a: params}, {
    arrayFormat: 'brackets'
})
// 结果是
'a[]=1&a[]=2&a[]=3'

// repeat
qs.stringify({a: params}, {
    arrayFormat: 'repeat'
})
// 结果是
'a=1&a=2&a=3'

处理json格式的参数
在默认情况下,json格式的参数会用 [] 方式编码

let json = { a: { b: { c: 'd', e: 'f' } } };

qs.stringify(json);
//结果 'a[b][c]=d&a[b][e]=f'

但是某些服务端框架,并不能很好的处理这种格式,所以需要转为下面的格式

qs.stringify(json, {allowDots: true});
//结果 'a.b.c=d&a.b.e=f'

需要注意的是:与JSON.stringify()的区别

JSON.stringify({"a": "1", "b": "2"})
//结果为:
'{"a": "1", "b": "2"}'

qs.stringify({"a": "1", "b": "2"})
//结果为:
'a=1&b=2'

axios传递数组参数get / delete请求方式解决方式如下

axios.get(url, {
 params: {
    ids: [1,2,3],
      type: 1
    },
    paramsSerializer: params => {
      return qs.stringify(params, { indices: false })
    }
})

axios.delete(url, {
    params: {
       ids: [1,2,3],
       type: 1
    },
    paramsSerializer: params => {
      return qs.stringify(params, { indices: false })
    }
})

post / put 请求方式解决方式如下

axios.post(url, qs.stringify(
    params: {
      ids: [1,2,3],
      type: 1
    }, 
    { indices: false }
))

axios.put(url, qs.stringify(
    params: {
     ids: [1,2,3],
     type: 1
    }, 
    { indices: false }
))
    
//url结果:
//url?ids=1&ids=2&id=3

qs.stringify({ids: [1, 2, 3]}, { indices: false })
//形式: ids=1&ids=2&id=3

qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘indices‘})
//形式: ids[0]=1&aids1]=2&ids[2]=3

qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘brackets‘})
//形式:ids[]=1&ids[]=2&ids[]=3

qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘repeat‘}) 
//形式: ids=1&ids=2&id=3