简体   繁体   中英

Image upload with React Native and Nodejs Express Multer

I have a Nodejs with Express server running on local that allow me to upload images, I did it with no problems on Postman, but when i tried to upload from React Native, the server get the request data, including the image, but do not upload it to server! What am i doing wrong here, please take a look!

here is my multer config:

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, './server/uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, new Date().toISOString() + file.originalname);
  }
})

const fileFilter = (req, file, cb) => {
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png' || file.mimetype === 'image') {
    cb(null, true);
  } else {
    cb(null, false);
  }
}

const upload = multer({ 
  storage: storage, 
  limits: {
    fileSize: 1024 * 1024 * 5
  },
  fileFilter: fileFilter,
});

here is my routes call:

route.post('/products', upload.single('image'), userAuthenticate, ProductController.createProduct);

here is my controller:

export const createProduct = async (req, res) => {
  try {
    console.log(req);

    const { serial, name, description, cate_id, quantity, origin_price, sell_price, attributes } = req.body;
    const newProduct = new Product({ serial, name, description, cate_id, quantity, origin_price, sell_price, attributes });

    newProduct._creator = req.user._id;

    // upload image  
    console.log(req.file);
    newProduct.image = fs.readFileSync(req.file.path);

    let product = await newProduct.save();
    let user = req.user;
    user._products.push(product);
    await user.save();
    return res.status(201).json({ product });
  } catch (e) {
    console.log(e.message);
    return res.status(e.status || 404).json({ err: true, message: e.message });
  }
}

and here is my post request from react native:

const data = new FormData();
    data.append('serial', serial);
    data.append('name', name);
    data.append('description', description);
    data.append('sell_price', [{ 'value': sell_price }]);
    data.append('origin_price', origin_price);
    data.append('quantity', quantity);
    data.append('cate_id', cate_id);
    data.append('attr', attr);
    data.append('image', {
      uri: image.uri,
      type: image.type,
      name: image.name
    });

    let product = await axios({
      method: 'POST',
      url: 'http://localhost:3000/api/products',
      data: data,
      headers: {
        Accept: 'application/json',
        'Content-Type': 'multipart/form-data', 
        'x-auth': token, 
      }
    })

And here is my image field in Product model:

image: {
    type: Buffer
  },

Recently I had the same problem, because there is an open issue See here on react native.

But I found a nice solution using rn-fetch-blob

as you may see in the documentation, you can implement the following:

upload = async () => {
    let ret = await RNFetchBlob.fetch(
      'POST',
      'http://localhost:3000/api/products',
      {
        'Content-Type': 'multipart/form-data',
        'x-auth': token, 
      },
      [
        {
          name: 'image',
          filename: Date.now() + '.png',
          type: 'image/png',
          data: RNFetchBlob.wrap(image.uri),
        },
      ],
    );
    return ret;
  };

As you see, there is an array, where you can add the objects you want to upload, just like in the FormData.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM