簡體   English   中英

僅在 Android 上使用 FormData 網絡錯誤獲取 React Native(帶 expo)

[英]React Native (with expo) fetch with FormData Network error on Android only

當我嘗試使用 fetch 和FormData在 POST 中使用 React native (expo SDK 37) 進行 fetch API 調用時,一切都在 IOS 上完美運行,但它在 Android: [TypeError: Network request failed]上出現網絡錯誤。 我有同樣的錯誤。網絡錯誤)如果我使用 axios 而不是獲取。

如果我用空的 {} 替換 formData,它就可以工作。 我已經檢查了模擬器和物理設備(各種 Android 版本),我嘗試使用標題但沒有結果。 我的 API 有一個有效的加密證書

let url = 'https://my-prod-server/webservice';

let formData = new FormData();
formData.append('test1','test1');
formData.append('test2','test2');

let request = await fetch(url, {
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'multipart/form-data',
  },
  method: 'POST',
  body: formData,
})
.then(response => response.json())
.catch(error => console.log('API ERROR: ', error));

return request;

這仍然存在於 Expo 46 中,並在 Github 問題中提出。

https://github.com/expo/expo/issues/8323#issuecomment-761675526

這是因為 Android 要求 file.type 比 iOS 更具體。

iOS 將接受'image' ,但 Android 將接受“ 'image/png' (或您使用的任何文件擴展名)

 const uriArray = result.uri.split(".");
 const fileExtension = uriArray[uriArray.length - 1];  // e.g.: "jpg"
 const fileTypeExtended = `${result.type}/${fileExtension}`; // e.g.: "image/jpg"

data.append('file', {
        uri: result.uri,
        name: image_name,
        type: type: fileTypeExtended
});

上面的塊與iOS和 Android 一起使用,感謝從上面 Github 線程中的@olapiv 復制。

我在嘗試使用 fetch 和 FormData 在 expo SDK 38 上發布圖像時遇到了同樣的問題。請求在 iPhone 上成功,而在 Android 上失敗,[TypeError: Network request failed]。 經過進一步調查,我發現我的請求根本沒有到達服務器,問題似乎出在僅使用 FormData 上。 帶有 FormData 的請求可能超時/被拒絕並導致錯誤。 當我遇到一篇提到 XMLHttpRequest 的帖子時,我浪費了大量時間尋找答案並嘗試實施建議的解決方案,但沒有任何幫助。 在這種特殊情況下,我最終使用了XMLHttpRequest而不是 fetch,它在 Android 設備和 iPhone 上與 FormData 一起工作就像一個魅力。

如下聲明一個函數,並用適當的值替換 < 和 > 之間的值

function sendXmlHttpRequest(data) {
  const xhr = new XMLHttpRequest();

  return new Promise((resolve, reject) => {
    xhr.onreadystatechange = e => {
      if (xhr.readyState !== 4) {
        return;
      }

      if (xhr.status === 200) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject("Request Failed");
      }
    };
    xhr.open("POST", <apiEndpoint>);
    xhr.setRequestHeader(<headerName>, <value>);
    xhr.send(data);
  });
}

現在在您的代碼中的某個地方,創建一個新的 FormData 對象並附加任何相關的字段/信息,然后最后調用將處理請求的 sendXmlHttpRequest 函數。

const photoData = new FormData();
photoData.append("photo", {
  uri: <uri of the photo>,
  name: filename,
  type: "image/jpeg"
});

const response = await sendXmlHttpRequest(photoData);

如果以上所有方法均失敗,您可能需要增加 nginx 服務器塊配置中的client_max_body_size

server {
    client_max_body_size 10M;

默認是1M 現在的 jpeg 還不夠。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM