【问题标题】:react-native-image-picker+axios uploads fail on Androidreact-native-image-picker+axios 在 Android 上上传失败
【发布时间】:2021-05-21 14:59:26
【问题描述】:

我有一个应用程序,我使用react-native-image-picker 拍摄和选择照片。然后我使用axiosFormData 将选定的文件上传到我的后端。

这在 iOS 上运行良好,我可以从图像选择器中获取 URL,并将其添加到我的 FormData 并将其发布到服务器。

但在 Android 上,当我使用相同的代码时,请求会停止。当我遗漏文件并且我的多部分表单数据中只有文本字段时,它可以发布。但是当我引用文件时,请求永远不会结束。

向网络服务器添加 CORS 支持并没有帮助。将服务器的域添加到network_security_config.xml 也无济于事。如前所述,只要不向 FormData/ 中添加任何文件,我就可以 GET 和 POST 到端点/

我可以看到我从图像选择器返回的 URI 在 Android 上是 content://my.app.id.imagepickerprovider/cacheDir/rn_image_picker_lib_temp_76d709ca-3d09-4b20-8ce4-bd8280180141.jpg 的样式,这似乎是一个无效的路径。

然后我研究了如何将 content:// 转换为有效的文件系统路径,并尝试了各种解决方案,在 RNFetchBlob 和 RNFS 中使用 stat(),但都没有奏效。我还尝试制作我自己的自定义模块,但它不起作用,最后安装了 react-native-get-real-path 模块,它似乎可以正确转换路径。我现在有类似/data/user/0/my.app.id/cache/rn_image_picker_lib_temp_638f24e9-0974-4fef-b6f0-e0a3873a14e6.jpg

所以现在,当我制作我的 FormData 时,我正在添加带有像 file:///data/user/0/my.app.id/cache/.....jpg 这样的 URI 的文件

但这仍然使我的 HTTP 请求挂起,就像我只是传递 content:// URI 一样。

我也尝试使用来自react-native-image-picker 的base64 输出,然后将data:... URI 设置为文件表单字段中的uri,这适用于iOS(但速度非常慢),不适用于Android。

我一定错过了什么——有什么提示吗?

在我的组件中:


const imagePickerCallback = useCallback((response: ImagePickerResponse) => {
    setCurrentPhoto(response)
  }, [])

const handleUpload = useCallback(async () => {
    const { uri, base64, fileName, fileSize, type } = currentPhoto
    fileUploadStore.add(uri, fileName, type, fileSize) 
  }, [currentPhoto, fileUploadStore])


我的FileUploadStore 调用我的 API,它尝试使用 URI 并调用 axios。 不同解决方案的结果在 cmets (actualUri) 中。

  async uploadFile(
    uri: string,
    name: string,
    type: string,
    onUploadProgress?: (progressEvent: ProgressEvent) => void,
    cancelToken?: CancelToken
  ): Promise<string> {
    const formData = new FormData()
    // Gives `NETWORK_ERROR` on android - file://content://dk.bosj.app.debug.imagepickerprovider/cacheDir/
    const actualUri = Platform.select({ ios: uri, android: `file://${uri}` })
    // Gives `NETWORK_ERROR` on android - /data/user/0/dk.bosj.app.debug/cache/rn_image_pi
    const actualUri = Platform.select({ ios: uri, android: await RNGRP.getRealPathFromURI(uri) })
    // Hangs forever on android  - content://dk.bosj.app.debug.imagepickerprovider/cacheDir/
    const actualUri = Platform.select({ ios: uri, android: uri })
    // Hangs forever on android  - file:///data/user/0/dk.bosj.app.debug/cache/rn_image_pi
    const actualUri = Platform.select({ ios: uri, android: `file://${await RNGRP.getRealPathFromURI(uri)}` })

    formData.append('file', {
      uri: actualUri,
      name,
      type,
    })
    console.log(JSON.stringify(formData))
    formData.append('stuff', 'AAAGNAAAA')
    const response = await this.api.post<{ id: string }, null>(BosjEndpoint.FILES, formData, {
      onUploadProgress,
      cancelToken,
    })
    if (!response.ok) {
      throw new Error(response.problem)
    }
    if (!response.data || !response.data.id) {
      throw new Error('DATA_ERROR')
    }
    return response.data.id
  }

【问题讨论】:

    标签: android react-native file-upload axios react-native-image-picker


    【解决方案1】:

    好的,问题与我尝试的解决方案相差甚远。

    在 Android 上更新 Flipper SDK 版本成功了,现在可以上传文件了!

    我从 0.37.0 更新到 0.75.1

    https://github.com/facebook/react-native/issues/28551#issuecomment-624347067

    【讨论】:

      猜你喜欢
      • 2020-03-13
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2020-09-16
      • 2021-09-28
      相关资源
      最近更新 更多