如何在 react-native 中使用 FormData?

IT技术 javascript react-native fetch-api
2021-02-27 20:05:33

嗨,刚学会使用 js 和 react-native。我不能使用 FormData 它总是显示不受支持的 bodyinit 类型。我想发送文本而不是 JSON.stringify。谁能帮我?谢谢!

var data = new FormData()
data.append('haha', 'input')

fetch('http://www.mywebsite.com/search.php', { 
  method: 'post',
  body: data
})
.then((response) => response.json())
.then((responseData) => {
  console.log('Fetch Success==================');
  console.log(responseData);

  var tempMarker = [];
  for (var p in responseData) {
   tempMarker.push({
    latitude: responseData[p]['lat'],
    longitude: responseData[p]['lng'] 
   })
  }

  this.setState({
    marker: tempMarker
  });

})
.catch((error) => {
  console.warn(error);
})
.done();
6个回答

这是我的简单代码 FormData,带有 react-native 来发布带有字符串和图像的请求。

我已经使用 react-native-image-picker 来捕捉/选择照片 react-native-image-picker

let photo = { uri: source.uri}
let formdata = new FormData();

formdata.append("product[name]", 'test')
formdata.append("product[price]", 10)
formdata.append("product[category_ids][]", 2)
formdata.append("product[description]", '12dsadadsa')
formdata.append("product[images_attributes[0][file]]", {uri: photo.uri, name: 'image.jpg', type: 'image/jpeg'})

注意您可以更改image/jpeg为其他内容类型。您可以从图像选择器响应中获取内容类型。

fetch('http://192.168.1.101:3000/products',{
  method: 'post',
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  body: formdata
  }).then(response => {
    console.log("image uploaded")
  }).catch(err => {
    console.log(err)
  })  
});
如果您有上述问题,请尝试向内容类型添加“边界” 'Content-Type': 'multipart/form-data; boundary=someArbitraryUniqueString
2021-04-24 20:05:33
2021-04-29 20:05:33
我可以知道 FormData 类是从哪里来的吗?我检查了 react-native-image-picker,它不在里面
2021-05-05 20:05:33
根据 MSDN 文档,FormData应该有一个set()方法(例如它在 Chrome 中),但显然这在 React Native 中不可用,所以解决方案确实是使用append()
2021-05-09 20:05:33
@bun:我按照上面的示例进行操作,但是服务器端的 req.body 始终为空,请帮忙
2021-05-19 20:05:33

这对我有用

var serializeJSON = function(data) {
  return Object.keys(data).map(function (keyName) {
    return encodeURIComponent(keyName) + '=' + encodeURIComponent(data[keyName])
  }).join('&');
}

var response = fetch(url, {
  method: 'POST',
  body: serializeJSON({
    haha: 'input'
  })
});
var response = fetch(url, { method: 'POST', body:encodeURIComponent("haha") + '=' + encodeURIComponent("input") });
2021-05-18 20:05:33
我怎么能只使用文本?不是 json
2021-05-21 20:05:33

如果要为 formData 项设置自定义内容类型:

var img = {
    uri : 'file://opa.jpeg',
    name: 'opa.jpeg',
    type: 'image/jpeg'
};
var personInfo = {
    name : 'David',
    age: 16
};

var fdata = new FormData();
fdata.append('personInfo', {
    "string": JSON.stringify(personInfo), //This is how it works :)
    type: 'application/json'
});

fdata.append('image', {
    uri: img.uri,
    name: img.name,
    type: img.type
});
有用!如果没有这个解决方案,所有请求都是使用 Content-Type: application/octet-stream 而不是 multipart/form-data 发送的。
2021-05-05 20:05:33

提供一些其他的解决方案;我们也在使用react-native-image-picker并且服务器端正在使用koa-multer此设置运行良好:

用户界面

ImagePicker.showImagePicker(options, (response) => {
      if (response.didCancel) {}
      else if (response.error) {}
      else if (response.customButton) {}
      else {
        this.props.addPhoto({ // leads to handleAddPhoto()
          fileName: response.fileName,
          path: response.path,
          type: response.type,
          uri: response.uri,
          width: response.width,
          height: response.height,
        });
      }
    });

handleAddPhoto = (photo) => { // photo is the above object
    uploadImage({ // these 3 properties are required
      uri: photo.uri,
      type: photo.type,
      name: photo.fileName,
    }).then((data) => {
      // ...
    });
  }

客户

export function uploadImage(file) { // so uri, type, name are required properties
  const formData = new FormData();
  formData.append('image', file);

  return fetch(`${imagePathPrefix}/upload`, { // give something like https://xx.yy.zz/upload/whatever
    method: 'POST',
    body: formData,
  }
  ).then(
    response => response.json()
  ).then(data => ({
    uri: data.uri,
    filename: data.filename,
  })
  ).catch(
    error => console.log('uploadImage error:', error)
  );
}

服务器

import multer from 'koa-multer';
import RouterBase from '../core/router-base';

const upload = multer({ dest: 'runtime/upload/' });

export default class FileUploadRouter extends RouterBase {
  setupRoutes({ router }) {
    router.post('/upload', upload.single('image'), async (ctx, next) => {
      const file = ctx.req.file;
      if (file != null) {
        ctx.body = {
          uri: file.filename,
          filename: file.originalname,
        };
      } else {
        ctx.body = {
          uri: '',
          filename: '',
        };
      }
    });
  }
}
使用它时,我得到: Expected URL scheme 'http' or 'https' but was 'file'
2021-05-07 20:05:33

在 react-native 中使用 formdata

我曾经react-native-image-picker选择照片。在我的情况下,从移动设备中选择了 photp 后。我将它的信息存储在 component 中state之后,我POST使用fetch如下方式发送 请求

const profile_pic = {
  name: this.state.formData.profile_pic.fileName,
  type: this.state.formData.profile_pic.type,
  path: this.state.formData.profile_pic.path,
  uri: this.state.formData.profile_pic.uri,
}
const formData = new FormData()
formData.append('first_name', this.state.formData.first_name);
formData.append('last_name', this.state.formData.last_name);
formData.append('profile_pic', profile_pic);
const Token = 'secret'

fetch('http://10.0.2.2:8000/api/profile/', {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "multipart/form-data",
      Authorization: `Token ${Token}`
    },
    body: formData
  })
  .then(response => console.log(response.json()))