JavaScript/React Native等效Python上传请求写法及415错误解决
问题背景
需要向Django REST服务端发送携带图片、位置、用户ID字段的POST请求,以下Python版本代码可正常运行:
with open(some_image, 'rb') as f: response = requests.post( url, files={ 'image': f, }, data={ 'longitude': SETTINGS[1]['long'], 'latitude': SETTINGS[1]['lat'], 'user_id': SETTINGS[1]['user_id'], })
在React Native环境下用axios实现相同逻辑时,返回415状态码,错误提示为Unsupported media type "application/json" in request.,原错误实现代码如下:
upload = async () => { let files = { 'image' : test // test is a base64 image file } let data = { 'longitude' : location["longitude"], 'latitude' : location["latitude"], 'user_id' : "test_id", } postUrl = "someurl"; axios.post(postUrl, files = files, data = data ).then( response => console.log(response) ).catch(function (error) { console.log(error.response); console.log(error); }); }
错误原因
- axios默认将请求体序列化为JSON格式,自动设置
Content-Type: application/json请求头,但带文件上传的请求需要使用multipart/form-data格式(即Python requests传入files参数时自动使用的编码格式),Django后端无法解析JSON格式的文件上传请求,因此返回415错误。 - 原代码axios传参语法错误,
axios.post第二个参数为完整请求体,不支持以files=xxx, data=xxx的形式拆分传参。 - 直接传入base64字符串作为文件字段,无法被后端识别为标准上传文件。
正确实现
使用Web标准的FormData对象构造请求体,和Python requests的files+data传参逻辑完全对齐,具体代码如下:
upload = async () => { const postUrl = "someurl"; const formData = new FormData(); // 处理base64图片,转为标准Blob对象 // 注意根据实际图片类型替换MIME值,比如image/png const base64Content = test.replace(/^data:image\/\w+;base64,/, ''); const imageBlob = await fetch(`data:image/jpeg;base64,${base64Content}`).then(res => res.blob()); // 追加图片文件字段,文件名可自定义 formData.append('image', imageBlob, 'upload.jpg'); // 追加普通表单字段 formData.append('longitude', location.longitude); formData.append('latitude', location.latitude); formData.append('user_id', "test_id"); // 发送请求,不要手动设置Content-Type请求头,由axios自动生成带boundary分隔符的合法请求头 try { const response = await axios.post(postUrl, formData); console.log(response); } catch (error) { console.log(error.response); console.log(error); } }
兼容说明
- 如果React Native环境下Blob转换存在兼容问题,且
test是本地图片的URI路径,可以直接用React Native约定的文件格式追加字段:
formData.append('image', { uri: test, name: 'upload.jpg', type: 'image/jpeg' });
- 若调整前端代码后仍返回415,需要检查Django服务端配置,确保
REST_FRAMEWORK的DEFAULT_PARSER_CLASSES中包含MultiPartParser,参考配置:
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.MultiPartParser', 'rest_framework.parsers.FormParser', ] }
内容的提问来源于stack exchange,提问作者Lumificier
相关产品推荐
相关产品推荐

