JavaScript提交含文件表单至PHP(Drupal)后端遇415错误求解决方案
解决表单提交(含文件)到Drupal后端的415错误问题
核心问题分析
你遇到的415错误(Unsupported Media Type)源于三个关键操作错误:
- 错误的数据序列化方式:将
FormData嵌套进JSON对象后用JSON.stringify处理,JSON无法序列化File或FormData类型,导致请求格式完全不符合后端要求。 - 错误的Content-Type设置:手动指定
application/json头,但上传文件需要使用multipart/form-data格式,且该格式的请求头需要浏览器自动生成的boundary分隔符,手动设置会丢失这个关键信息。 - 不必要的no-cors模式:该模式会限制浏览器处理响应的能力,若后端未配置CORS,反而会加剧跨域问题,应直接移除。
修正后的代码实现
直接使用FormData承载所有表单字段(文本+文件),让浏览器自动处理请求头和数据格式:
<form method="post" enctype="multipart/form-data"> <input type="text" name="first_name" id="first_name"> <input type="text" name="surname" id="surname"> <textarea name="message" id="message" cols="30" rows="10"></textarea> <input type="file" name="sample_image" id="sample_image"> <div id="uploaded_image"></div> </form> <script> const first_name = document.querySelector("#first_name"); const surname = document.querySelector("#surname"); const message = document.querySelector("#message"); const sample_image = document.getElementsByName("sample_image")[0]; sample_image.addEventListener('change', e => { e.preventDefault() upload_image(sample_image.files[0]) }) const upload_image = (file) => { const form_data = new FormData(); // 添加所有文本字段 form_data.append("webform_id", "springboks"); form_data.append("first_name", first_name.value); form_data.append("surname", surname.value); form_data.append("message", message.value); // 添加文件字段(字段名需与后端接收的名称一致,视频字段同理替换) if (file) { form_data.append("sample_image", file); } fetch("http://localhost:49640/api/v1/form/14436545/CBUFormSubmission", { method: "POST", // 移除手动的Content-Type和no-cors模式,由浏览器自动处理请求头 body: form_data }) .then(function(response){ if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } return response.json(); }) .then(function(responseData){ console.log("提交成功:", responseData); }) .catch(function(error){ console.error("提交失败:", error); }) } </script>
额外注意事项
- CORS配置:确保Drupal后端已配置CORS规则,允许你的前端域名发起跨域请求,否则会出现跨域权限错误。
- 字段名一致性:
FormData中append的字段名必须与Drupal webform定义的字段名完全匹配(比如你提到的视频字段,需替换为后端对应的字段名)。 - 触发时机调整:当前代码在文件选择时触发提交,可根据需求修改为点击提交按钮触发,确保所有文本字段填写完整后再提交。
内容的提问来源于stack exchange,提问作者Sidney Sousa
相关产品推荐
相关产品推荐

