问题描述
vue开发的时候,发现get请求的参数值为null,这个参数会被删除掉,在后端检查这个参数时不存在就会报错。
Example:
入力参数: { foo: null, bar: "baz", qux: undefined }
变换后的参数: ?bar=baz
foo被删除了,后台参数检查时发现foo不存在,就会报错
参照
https://github.com/axios/axios/issues/1139
这个问题在axios:release/1.0.0-beta.1中被修改,但是没有反映到稳定版中
https://github.com/axios/axios/pull/1987
解决方案
1.这个问题在release/1.0.0-beta.1据说解决了,但是不敢使用测试版
2.使用qs模块替换axios中有问题参数序列化模块
axios官网也推荐使用qs来代替原来的模块,原来的模块还有其他问题,比如说嵌套对象也会出问题https://github.com/nodejs/node-v0.x-archive/issues/1665
https://github.com/axios/axios#config-defaults
// `paramsSerializer` is an optional function in charge of serializing `params`
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
修改方法1
config.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'brackets' })
Example:
入力参数: { foo: null, bar: "baz", qux: undefined }
变换后的参数: ?foo=&bar=baz
相当于变成了空字符串
修改方法2
config.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'brackets', strictNullHandling: true })
Example:
入力参数: { foo: null, bar: "baz", qux: undefined }
变换后的参数: ?foo&bar=baz
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
config.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'brackets', strictNullHandling: true })
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
这种方法php或者是cakephp不能很好解析,依然解析成了空字符串,或许是这个问题迟迟不能反映到稳定版中的原因。
Example:
This params object: { foo: null, bar: "baz", qux: undefined }
Becomes this query string: ?foo&bar=baz
qs官网
https://github.com/ljharb/qs
3.不使用null,前台用空字符串代替
4.后台使用null参数的时候,作为可选参数,用array_key_exists或isset先判断一下,避免了参数检查错误
5.完全不使用参数检查
6.配合方案2,不使用php的参数解析,自己解析
第一推荐使用方案4
由于现在的php无法正确解析null,要回避这个问题,需要用方案4。
第二推荐使用方案2,由于php的参数解析问题,变成了空字符串,依然不完美,并不能正确传送null值。
为了让php能正常解析null参数,写了一个php的函数,把空字符串重新设置成正确的null值。
function getQuery($queryString){
parse_str($queryString, $query);
preg_match_all(
'/(?:^|&)([^&=$]+)[&|$]/',
$queryString,
$matches
);
foreach($matches[1] as $item){
parse_str($item, $temp);
foreach($temp as $k=>$v)
$query[$k] = null;
}
return $query;
}
调用方法
$query2=getQuery($_SERVER['QUERY_STRING']);
Example:
入力参数: { foo: null, bar: "baz", qux: undefined }
变换后的参数: ?foo&bar=baz
PHP解析后的参数
"array ( 'foo' => NULL, 'bar' => 'baz', )"
php完美解析null值
php以外的语言或许已经可以识别?foo&bar=baz这样的参数,能把foo设置成null,我没有试过。