如何使用JavaScript调用携带图片在请求体中的POST API
调用携带图片的POST API返回400错误的问题
我尝试调用一个需要在请求体中携带图片的POST API,但所有试过的方案都返回400错误,具体尝试内容如下:
方案1:使用FileReader的readAsDataURL()
尝试通过FileReader读取图片并发送请求,出现undefined错误:
let reader = new FileReader() reader.readAsDataURL(event.target.files[0]); fetch('some endpoint', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: reader, // 也试过用reader.result }) .then((response) => response.json()) .then((json) => console.log(json))
方案2:使用FormData
用FormData封装文件发送请求,同样返回400错误:
HTML代码
<form class="form" id="myForm"> <input type="file" id="fileUpload" accept="image/*" onchange="previewImage(event);"/> </form>
JavaScript代码
const inpFile = document.getElementById('fileUpload'); const formData = new FormData(); formData.append('inpFile', event.target.files[0]); fetch('some endpoint', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: formData, }) .then((response) => response.json()) .then((json) => console.log(json))
错误截图:
问题分析与解决方法
方案1的问题
- FileReader是异步操作:
readAsDataURL不会立即生成结果,直接在调用后发送请求时,reader.result还未赋值,因此会出现undefined。 - 请求格式错误:即便拿到Base64结果,也不能直接将其作为请求体,需要包裹进JSON对象中,同时确保后端支持解析Base64格式的图片。
修正后的方案1代码:
let reader = new FileReader(); // 等待FileReader异步读取完成 reader.onload = function(e) { fetch('some endpoint', { method: 'POST', headers: {'Content-Type': 'application/json'}, // 将Base64字符串放入JSON对象中发送 body: JSON.stringify({ image: e.target.result }) }) .then((response) => response.json()) .then((json) => console.log(json)) .catch(err => console.error(err)); }; reader.readAsDataURL(event.target.files[0]);
方案2的问题
手动设置Content-Type错误:使用FormData发送文件时,浏览器会自动设置正确的Content-Type为multipart/form-data并携带边界标识,手动指定application/json会导致后端无法解析请求体,从而返回400错误。
修正后的方案2代码:
const formData = new FormData(); formData.append('inpFile', event.target.files[0]); fetch('some endpoint', { method: 'POST', // 无需手动设置Content-Type,交给浏览器自动处理 body: formData, }) .then((response) => response.json()) .then((json) => console.log(json)) .catch(err => console.error(err));
内容的提问来源于stack exchange,提问作者Vinodh Ganesh
相关产品推荐
相关产品推荐

