使用Axios提交POST请求存表单数据时遭遇SQL非空约束错误求助
首先看你碰到的这个错误:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'cuAddress' cannot be null
这说明后端压根没收到cuAddress字段的值,导致插入数据库时该字段为null,触发了非空约束。问题出在你Axios请求的数据处理和请求头设置上,具体原因和修复方案如下:
问题到底出在哪?
你用$(frmObj).serialize()得到的是URL编码的表单字符串(比如cuAddress=北京XX路&username=vino),但直接把这个字符串丢给Axios的body参数时,Axios不会自动帮你设置正确的请求头,后端无法正确解析这些表单数据,结果就是所有字段值都没被正确读取,cuAddress自然就成了null,触发SQL错误。
而你用jQuery的Ajax能成功,是因为$.ajax默认会做两件事:一是把序列化后的字符串作为请求体,二是自动添加Content-Type: application/x-www-form-urlencoded请求头,后端一看就知道怎么解析这些数据,所以请求正常。
两种修复方案任你选
方案一:手动补全正确的请求头
在Axios的配置里加上Content-Type请求头,同时把body换成Axios标准的data参数(虽然body也能用,但data是官方推荐的):
var url = "https://www.webprogr.com/tmp/labs/www/mani/hyperlocal-restful/v1/booking"; var sData = $(frmObj).serialize(); axios(url, { method: 'post', data: sData, headers: { "Authorization": api_key, "Content-Type": "application/x-www-form-urlencoded" } }).then(function(response) { console.log(response); return response.data; }).then(function(data) { console.log(data); console.log(sData); });
方案二:用FormData更规范地传递表单数据
如果你的表单以后可能加文件上传,或者想更标准地处理表单数据,直接用FormData就好,它会自动处理数据格式和请求头:
var url = "https://www.webprogr.com/tmp/labs/www/mani/hyperlocal-restful/v1/booking"; var formData = new FormData(frmObj); // 直接把表单元素传进去就行,不用手动序列化 axios(url, { method: 'post', data: formData, headers: { "Authorization": api_key, // FormData会自动设置这个头,不过手动写上也没问题 "Content-Type": "multipart/form-data" } }).then(function(response) { console.log(response); return response.data; }).then(function(data) { console.log(data); });
为啥Fetch也会出同样的问题?
道理和Axios一样,Fetch默认也不会自动设置application/x-www-form-urlencoded请求头,如果你直接传序列化后的字符串,必须手动加请求头,或者用FormData,不然后端照样解析不了数据,自然会报同样的错误。
内容的提问来源于stack exchange,提问作者vino

