首页 > 解决方案 > 从 iOS 上传图片太慢

问题描述

我的 React-Native iOS 前端无法将图像上传到我的 Node.JS (Express + Multer) 后端。

我的前端是 React Native Android & iOS。Android 版本运行良好,没有任何问题,但是,从 iOS 设备上传图像大部分时间都不起作用。

发送上传请求后,我可以看到图像文件已添加到 FTP 中,但是速度非常慢,例如每秒几 KB。500 KB 的图像在请求超时之前可能需要 3 分钟或更长时间。该文件被部分添加到服务器中,每次刷新时我都可以看到大小的变化。

一些 [iOS] 设备完全没有问题,上传速度很快,但是,绝大多数设备都遇到了这个问题。

没有连接问题。相同的主机和网络与 Android 完美配合。与某些iOS 设备相同。

这不限于特定的 iOS 版本或设备。但是,有问题的设备总是有问题,而没有问题的设备则永远不会

我该如何解决这个问题?

发布请求:

router.post('/image', (req, res) => {
    console.log('image')
    upload(req, res, (error) => {
        if (error) {

            console.log(error)
            return res.send(JSON.stringify({
                data: [],
                state: 400,
                message: 'Invalid file type. Only JPG, PNG or GIF file are allowed.'
            }));
        } else {
            if (req.file == undefined) {
                console.log('un')

                return res.send(JSON.stringify({
                    data: [],
                    state: 400,
                    message: 'File size too large'
                }));
            } else {
                var CaseID = req.body._case; // || new mongoose.Types.ObjectId(); //for testing
                console.log(req.body._case + 'case')
                var fullPath = "uploads/images/" + req.file.filename;
                console.log(fullPath);
                var document = {
                    _case: CaseID,
                    path: fullPath
                }

                var image = new Image(document);

                image.save(function(error) {
                    if (error) {
                        console.log(error)
                        return res.send(JSON.stringify({
                            data: [],
                            state: 400,
                            message: 'bad request error'
                        }));
                    }
                    return res.send(JSON.stringify({
                        data: image,
                        state: 200,
                        message: 'success'
                    }));
                });
            }
        }
    });

});

上传.js:

const multer = require('multer');
const path = require('path');

//image upload module

const storageEngine = multer.diskStorage({
    destination: appRoot + '/uploads/images/',
    filename: function (req, file, fn) {
        fn(null, new Date().getTime().toString() + '-' + file.fieldname + path.extname(file.originalname));
    }
});


const upload = multer({
    storage: storageEngine,
    // limits: {
    //     fileSize: 1024 * 1024 * 15 // 15 MB
    // },
    fileFilter: function (req, file, callback) {
        validateFile(file, callback);
    }
}).single('image');

var validateFile = function (file, cb) {
    // allowedFileTypes = /jpeg|jpg|png|gif/;
    // const extension = allowedFileTypes.test(path.extname(file.originalname).toLowerCase());
    // const mimeType = allowedFileTypes.test(file.mimetype);
    // if (extension && mimeType) {
    //     return cb(null, true);
    // } else {
    //     cb("Invalid file type. Only JPEG, PNG and GIF file are allowed.")
    // }
    var type = file.mimetype;
    var typeArray = type.split("/");
    if (typeArray[0] == "image") {
      cb(null, true);
    }else {
      cb(null, false);
    }
};


module.exports = upload;

React Native 上传功能:

    pickImageHandler = () => {
            ImagePicker.showImagePicker(this.options1, res => {
                    if (res.didCancel) {
                    } else if (res.error) {
                    } else {
                            this.setState({upLoadImage:true})
                            var data = new FormData();
                            data.append('image', {
                              uri: res.uri, 
                              name: 'my_photo.jpg',
                              type: 'image/jpg'
                            })
                            data.append('_case',this.state.caseID)

                            fetch(url+'/image'
                            , {method:'POST',
                            body:data
                            }
                             )
                            .then((response) => response.json())
                            .then((responseJson) =>
                            {
                                    this.setState(prevState => {
                                            return {
                                                    images: prevState.images.concat({
                                                            key: responseJson._id,
                                                            src: res.uri
                                                    })
                                            }

                                    }

                                    )   
                                    this.setState({upLoadImage:false})


                            })

                            .catch((error) =>
                            {
                              alert(error);
                            });


                    }
            }
            )
    }

有什么建议么?

谢谢

标签: node.jsreact-nativeexpressreact-native-iosmulter

解决方案


我从 UpWork 看到您的回答,请尝试这种方式,我正在使用 API Sauce 进行 API 调用

export const addPartRedux = (data) => {
    return (dispatch, getState) => {
        console.log('addPArtREdux', data);
        const values = {
            json_email: data.token.username,
            json_password: data.token.password,
            name: data.text ? data.text : '',
            car: data.selected.ID,
            model: data.selectedSub.ID,
            make_year: data.selectedYear,
            type: data.type,
            ImportCountry: data.import_image ? data.import_image : '',
            FormNumber: data.number ? data.number : '',
            do: 'insert'
        };
        const val = new FormData();
        Object.keys(values).map((key) =>
            val.append(key, values[key])
        );
        if (data.imageok) {
            val.append('image', {
                uri: data.image.uri,
                type: data.image.type,
                name: data.image.name
            });
        }
        dispatch(loading());
        api
            .setHeader('Content-Type', 'multipart/form-data;charset=UTF-8');
        api
            .post('/partRequest-edit-1.html?json=true&ajax_page=true&app=IOS',
                val,
                {
                    onUploadProgress: (e) => {
                        console.log(e);
                        const prog = e.loaded / e.total;
                        console.log(prog);
                        dispatch(progress(prog));
                    }
                })
            .then((r) => {
                console.log('Response form addPartRedux', r.data);
                if (r.ok === true) {
                    const setting = qs.parse(r.data);
                    dispatch(addpart(setting));
                } else {
                    dispatch(resetLoading());
                    dispatch(partstError('Error Loading '));
                }
            })
            .catch(
                (e) => {
                    console.log('submitting form Error ', e);
                    dispatch(resetLoading());
                    dispatch(partstError('Try Agin'));
                }
            );
    };
};


推荐阅读