【问题标题】:Post Image as FormData sets content-type as text/plain;charset=UTF-8Post Image as FormData 设置 content-type 为 text/plain;charset=UTF-8
【发布时间】:2019-02-20 09:06:34
【问题描述】:

我有一个两部分的问题。

  1. FormData() 在发送图像时未正确设置Content-Type。我该如何解决?

  2. 如何将图像读取为二进制而不是react-native 中的base64

我正在尝试以 react-native 将图像上传到服务器。

使用react-native-image-picker,我可以选择图像并获取它的uri(甚至base64)。

然后我创建一个FormData() 并通过fetch 发布它(甚至尝试使用axiosXMLHttpRequest)。但是content-type 设置为text/plain;charset=UTF-8,所以req.filesundefined

但是,当我手动向 send the image (shown in 'Dealing with Binary Data' section) 创建XMLHttpRequest 请求时,我可以发送图像。但是图像数据是在base64而不是binary中编码的。

XMLHttpRequestFormData 的代码

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', res=>{console.log(res)} )
xhr.addEventListener('error', err=>{console.log(err)} )

xhr.open('POST', global.config.getServerAddress() + this.props.api);
xhr.setRequestHeader( 'Authorization', 'Bearer ' +  global.config.token )

const formdata = new FormData();
formdata.append( this.props.label, { name: this.props.label, type: type, fileName: uri.split('/').pop() });

xhr.send(formdata);

手动XMLHttpRequest 请求的代码有效。但需要将图像数据发送为binary,而不是base64

const boundary = "myboundary"
let data = ""
data += "--" + boundary + "\r\n"
data += 'content-disposition: form-data; '
// Define the name of the form data
      + 'name="' + this.props.label + '"; '
// Provide the real name of the file
      + 'filename="'     + uri.split('/').pop() + '"\r\n'
// And the MIME type of the file
data += 'Content-Type: ' + type + '\r\n'

// There's a blank line between the metadata and the data
data += '\r\n'

// Append the binary data to our body's request
data += `data:${type};base64,` + image + '\r\n'
data += "--" + boundary + "--"

var XHR = new XMLHttpRequest()

XHR.addEventListener('load', callbackConf.callback )

XHR.addEventListener('error', callbackConf.errorCallback )

XHR.open('POST', global.config.getServerAddress() + this.props.api )
XHR.setRequestHeader( 'Authorization', 'Bearer ' +  global.config.token )
XHR.setRequestHeader( 'Content-Type', 'multipart/form-data; boundary=' + boundary )

XHR.send( data )

【问题讨论】:

标签: react-native xmlhttprequest multipartform-data content-type


【解决方案1】:

对于您的第一个查询,试试这个(我使用了this picker):

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

formdata.append("description", 'my-image')
formdata.append("image", {uri: photo.uri, name: 'image.jpg', type: 'multipart/form-data'})


fetch('YOUR_URL',{
  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' 放在标题中,我需要提供一个边界。 Fetch 没有更新边界,服务器给出了一个错误,说没有找到边界。
  • 在 react native 中发送多部分的最佳方式。我不确定你的服务器代码!
  • 服务器代码有效,因为如果我手动创建边界并将 Content-type 发送到 multipart (第二个代码),它就可以工作。但是,当我将 Content-type 单独设置为 'multipart/form-data' 时,服务器不知道发送数据的边界,因此会出错。我在这里遇到了一个问题,因为第二个代码发送的是 base64 图像数据而不是二进制文件。第一种方法应该发送一个二进制文件,但由于 Content-type 标头不正确,服务器无法正确解析它。我不知道为什么 fetch 没有设置正确的标题..
【解决方案2】:

我是通过fetch 完成的,将数据附加到表单数据中:

const data = new FormData(); data.append('image', { uri: uri, type: 'image/jpeg', name: 'random.jpg' }); data.append('idUser', this.state.idUser);
发送即可:

fetch(uriApi, { method: 'post', body: data }).then((response) => response.json()) .then((responseJson) =>{console.log(responseJson)})

【讨论】:

  • 我已经尝试过了,但由于某种原因它无法正常工作。内容类型设置为 text/plain;charset=UTF-8。
  • 奇怪..不知道为什么会这样..也许看到这个:github.com/facebook/react-native/issues/5308 有你的一些问题和一些解决方案
猜你喜欢
  • 2020-07-30
  • 2023-02-06
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 2011-06-09
相关资源
最近更新 更多