CodeIgniter4中如何处理$this->request->getRawInput()获取的FormData数据
问题根源
CodeIgniter4 仅会自动解析 POST请求 下的 multipart/form-data 格式(也就是你用FormData提交的格式),对于PUT、DELETE等REST请求类型,默认不会解析这类格式的请求体,你调用getRawInput()拿到的就是未处理的原始请求字符串,所以会出现WebKitFormBoundary边界标识。
解决方案
方案1:无文件上传需求时,直接用JSON格式提交(最简便)
如果你当前的表单不需要上传文件,完全没必要使用FormData,直接提交JSON格式数据即可,前后端修改都很少:
前端修改代码:
$('#updateStudentInfoBtn').click(function(e){ // 修复原代码bug:apiUrl没有替换真实的studentUUID let studentUUID = $('[name=studentUUID]').val(); let apiUrl = "/api/students/" + studentUUID; var formObj = { firstname : $('[name="firstname"]').val(), middlename : $('[name="middlename"]').val(), lastname : $('[name="lastname"]').val(), gender : $('[name="gender"] option:selected').val(), dob : $('[name="dob"]').val(), admission_date : $('[name="admission_date"]').val(), admission_stage : $('[name="admission_stage"]').val(), current_stage : $('[name="current_stage"]').val(), current_section : $('[name="current_section"]').val(), name_of_guardian : $('[name="name_of_guardian"]').val(), relationship_to_student : $('[name="relationship_to_student"]').val(), occupation : $('[name="occupation"]').val(), phone_no : $('[name="phone_no"]').val(), }; $.ajax({ method: "PUT", url: apiUrl, // 直接传序列化后的JSON字符串 data: JSON.stringify(formObj), contentType: "application/json", cache: false, success: function(res){ // 修复原代码bug:不要把响应对象转成字符串,否则拿不到status属性 if(res.status == 201) { // 展示成功提示 } //location.href="/admin/allstudents"; }, error: function(err){ console.log(err); } }); });
后端修改代码:
直接用CI4提供的getJSON()方法获取解析后的关联数组即可:
public function update($studentUuid = null) { $studentModel = new StudentModel(); $studentData = $studentModel->where('uuid', $studentUuid)->first(); // 传true表示返回关联数组,不传返回对象 $input = $this->request->getJSON(true); // 直接获取字段 比如 $input['firstname'] print_r($input); }
方案2:有文件上传需求必须用FormData的情况
如果你的表单后续要加文件上传功能,必须使用FormData,可以用_method参数伪请求的方式处理:
前端修改:
把请求方式改成POST,在FormData里追加_method=PUT参数,CI4会自动识别为PUT请求,同时POST请求的FormData会被自动解析:
// 原有构造formObj、form_data的代码不变 form_data.append('_method', 'PUT'); $.ajax({ method: "POST", // 改成POST url: apiUrl, data: form_data, processData : false, contentType : false, cache: false, // 其余回调代码保持不变 });
后端修改:
直接用常规的POST参数获取方法拿值即可:
public function update($studentUuid = null) { $studentModel = new StudentModel(); $studentData = $studentModel->where('uuid', $studentUuid)->first(); // 获取所有提交的参数 $input = $this->request->getPost(); // 单个字段也可以直接 $this->request->getPost('firstname') // 上传的文件用 $this->request->getFile('文件名') 即可 print_r($input); }
额外修复的已知问题
你原有代码存在两个隐性bug,上面的方案中已经同步修复:
- 原
apiUrl没有替换为真实的studentUUID值,会导致请求地址错误 - 原success回调中错误地对响应对象做了
JSON.stringify处理,转成字符串后无法读取status属性
内容的提问来源于stack exchange,提问作者Osborne Mordreds
相关产品推荐
相关产品推荐

