最近遇到一个react-native中使用react-native-image-crop-picker上传图片的问题,纠结了好久。直接上代码:
// react-native App.js
// ...
global.XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest
function App() {
// ...
return (
// ...
)
}
// react-native a页面
import ImagePicker from 'react-native-image-crop-picker'
import axios from 'axios'
// ...
const xxxScreen = () => {
// ...
const uploadImage = async () => {
const image = await ImagePicker.openCamera(options) // 或者ImagePicker.openPicker, options省略
try {
const data = new FormData()
data.append('file', {
uri: image.path,
type: image.mime,
name: createFilename(image) // createFilename:获取文件名的封装
})
const res = await axios.post('your_upload_url', data)
console.log(res)
} catch(error) {
console.log(error)
}
}
}
// node(express) app.js
const fileUpload = require('express-fileupload');
// ...
app.use(
fileUpload(options) // options省略
);
// node(express) controller.js
module.exports = {
async upload(req, res, next) {
console.log(req.files) // undefined
}
}
问题是:express中接收文件的接口中req.files始终是undefined
排查过程:
- 刚开始认为是Content-Type设置问题,应该设置multipart/form-data。结果设置无效,在看过axios源码之后你就会知道,如果上传formData,axios会删除Content-Type
if (utils.isFormData(requestData)) { delete requestHeaders['Content-Type']; // Let the browser set it }
- 更换fetch,结果仍然无效
- 终于在https://github.com/axios/axios/issues/1321中找到了答案,答案就在react-native App.js中
global.XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest
注释掉它就能恢复内心的平静
finally, innerpeace...