React Native Fetch 問題

Fetch Request

web 環(huán)境下 Request Body 支持的 參數(shù) 類型有: String, URLSearchParams, Blob/File, FormData, ArrayBuffer, ArrayBufferView

不同之處
① RN 自身本僅支持 XMLHttpRequest 進(jìn)行網(wǎng)絡(luò)請求,支持的 Request Body 可通過 源碼1 > 源碼2 > 源碼3 查看,缺少了對 URLSearchParams 的支持南捂。
② RN Fetch 使用 whatwg-fetch,通過 XMLHttpRequest 實(shí)現(xiàn)了 Fetch 功能继蜡,根據(jù) 源碼1源碼2 可以看出 whatwg-fetch 支持 URLSearchParams 類型的 Request Body ,但在 RN 中少了臨門一腳逛腿。

String

body 為 String稀并,請求格式如下

fetch
content-type: text/plain;charset=UTF-8
---------------------------
string

URLSearchParams

body 為 URLSearchParams,請求格式如下

fetch
content-type: application/x-www-form-urlencoded;charset=UTF-8
---------------------------
String(URLSearchParams): foo=foo&bar=bar

不同之處:根據(jù) web 示例单默,支持 new URLSearchParams("foo=foo&bar=bar")碘举,但根據(jù) RN 源碼,僅支持 new URLSearchParams({foo:"foo", bar:"bar"}) 形式搁廓,且沒有實(shí)現(xiàn) get引颈、has、set 等方法境蜕。

Blob/File

body 為 Blob蝙场,請求格式如下

fetch
content-type: Blob.type
---------------------------
String(Blob)

不同之處:根據(jù) Blob 文檔RN 源碼
① 可以看到 RN Blob 未實(shí)現(xiàn) arrayBufferstream粱年、text 方法售滤。
② 創(chuàng)建 Blob 對象 new Blob(array, options) 中的 array 參數(shù),RN 只能使用 StringBlob逼泣,而不能使用 ArrayBuffer趴泌、ArrayBufferView

關(guān)于 RN Blob (File 是繼承 Blob 實(shí)現(xiàn)的,二者基本一致拉庶,不再累述):

在瀏覽器中嗜憔,Blob 對象的數(shù)據(jù)緩存在瀏覽器中并與變量指針綁定。在 RN 中氏仗,Blob 對象的數(shù)據(jù)將緩存在原生端(其實(shí)也就是 app 運(yùn)行內(nèi)存中)吉捶,并生成一個唯一的 id,返回給 js 端皆尔,也就是說在 js 端存儲的僅是一個 id呐舔。后續(xù)則可通過 FileReader 與原生端交互,讀取 Blob 對象的實(shí)際數(shù)據(jù)慷蠕。Fetch 函數(shù)內(nèi)部已實(shí)現(xiàn)了數(shù)據(jù)讀取珊拼,可將 Blob 直接設(shè)置為 Request Body

Blob 的創(chuàng)建方式:

① 通過函數(shù)流炕,比如 Fetch / XMLHttpRequest 請求可以獲取到 Response Blob澎现,網(wǎng)絡(luò)請求是在原生端完成的,完成后原生端緩存響應(yīng)結(jié)果每辟,返回唯一 id 給 js 端創(chuàng)建 Blob剑辫。

② 也可以使用如下方法直接創(chuàng)建,js 會先將創(chuàng)建數(shù)據(jù)傳遞給原生端緩存渠欺,然后使用原生端返回的唯一 id 創(chuàng)建 Blob

const body = new Blob(
   ['<a id="a"><b id="b">hey!</b></a>'], 
   {type : 'text/html', lastModified:Date.now()}
);

-> 創(chuàng)建 -> string 傳到原生端 -> 返回 id -> js{id:....,type,}

const stream = new Blob(
   [body, 'string'], 
   {type : 'text/html', lastModified:Date.now()}
);

-> 傳遞參數(shù) body 的 id 和 string -> 返回新 id -> js{id:...,type,}

FormData

body 為 Blob妹蔽,請求格式如下 (以上 body 格式的 header content-typewhatwg-fetch 實(shí)現(xiàn),以下 header content-type 則在原生的 Android 端挠将、iOS 端 實(shí)現(xiàn) )

fetch
content-type: multipart/form-data; boundary=...
---------------------------
String(FormData)

不同之處:根據(jù) FormData 文檔RN 源碼胳岂,可以看到有以下不同
① RN 僅實(shí)現(xiàn)了 appendgetParts 方法捐名,而沒有實(shí)現(xiàn) get旦万、hasset 等方法镶蹋。如果在 RN 中需要對已添加的 form data 進(jìn)行修改成艘,可通過 FormData._parts 進(jìn)行操作,但這種方法并不安全贺归,后續(xù) RN 可能會對 _parts 更新淆两,造成兼容性問題。
append 方法與瀏覽器端的實(shí)現(xiàn)不同

// 瀏覽器, value 支持 String / File / Blob
var formData = new FormData();
formData.append('username', 'Chris');
formData.append('userpic', myFileInput.files[0], 'chris.jpg');
formData.append('blob', new Blob(
   ['<a id="a"><b id="b">hey!</b></a>'], 
   {type : 'text/html', lastModified:Date.now()}
));

// RN, value 支持 String / FIle
var formData = new FormData();
formData.append('username', 'Chris');
formData.append('userpic', {
    uri: String,
    type: 'image/jpeg',
    name: 'photo.jpg',
});

關(guān)于 RN FormData 的幾點(diǎn)說明

  • 查看 iOS源碼Android 源碼拂酣,可以看出在原生端 RN 并未支持 FormData 添加 Blob 類型數(shù)據(jù)秋冰。
  • RN 給了另外一種上傳文件的方式,通過 {uri, ...} 指定文件地址婶熬,uri 支持 file://, content://(Android), 甚至還支持 http:// 網(wǎng)絡(luò)圖片
  • 如果必須要求 FormData 支持 Blob 對象剑勾,有兩種拓展思路(需自行實(shí)現(xiàn))
    • 先將 Blob 對象保存為臨時文件埃撵,然后通過 {uri, ...} 添加,待請求完成后刪除臨時文件虽另,這種方式會產(chǎn)生臨時文件暂刘,且本來 Blob 對象已在內(nèi)存中,保存為文件捂刺,發(fā)送請求谣拣,原生端會再次讀取臨時文件到內(nèi)存中,有點(diǎn)浪費(fèi)族展。
    • Request body 支持 Blob 對象森缠,可根據(jù) 規(guī)則 自行將 formData 轉(zhuǎn)換為 multipart/form-data 類型的 Blob 數(shù)據(jù),如果 formData 中包含 {uri, ...} 類型文件仪缸,則需要將該類型轉(zhuǎn)為 Blob 對象才能與 formData 中的其他 String贵涵、Blob 對象整合為一個統(tǒng)一的 Blob 對象,實(shí)現(xiàn)起來略微麻煩點(diǎn)恰画。
    • 所以独悴,如果可以調(diào)整思路避開使用 FormData Blob,就盡量避開吧

ArrayBuffer / ArrayBufferView

fetch
content-type: ......
---------------------------
String(ArrayBuffer)

ArrayBuffer 將作為 Request body 發(fā)送锣尉,與 Blob/File 相似刻炒,不同之處在于:在發(fā)送請求時,必須要在 Request.Headers 中指定 content-type自沧,否則會請求失敗坟奥。(而 Blob/File Body 則無需,在未指定的情況下會使用 application/octet-stream 作為 content-type 默認(rèn)值)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拇厢,一起剝皮案震驚了整個濱河市爱谁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孝偎,老刑警劉巖访敌,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異衣盾,居然都是意外死亡寺旺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門势决,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阻塑,“玉大人,你說我怎么就攤上這事果复〕旅В” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長走搁。 經(jīng)常有香客問我独柑,道長,這世上最難降的妖魔是什么私植? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任群嗤,我火速辦了婚禮,結(jié)果婚禮上兵琳,老公的妹妹穿的比我還像新娘。我一直安慰自己骇径,他們只是感情好躯肌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著破衔,像睡著了一般清女。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晰筛,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天嫡丙,我揣著相機(jī)與錄音,去河邊找鬼读第。 笑死曙博,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怜瞒。 我是一名探鬼主播父泳,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吴汪!你這毒婦竟也來了惠窄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤漾橙,失蹤者是張志新(化名)和其女友劉穎杆融,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霜运,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脾歇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了淘捡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片介劫。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖案淋,靈堂內(nèi)的尸體忽然破棺而出座韵,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布誉碴,位于F島的核電站宦棺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黔帕。R本人自食惡果不足惜代咸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望成黄。 院中可真熱鬧呐芥,春花似錦、人聲如沸奋岁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闻伶。三九已至滨攻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蓝翰,已是汗流浹背光绕。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畜份,地道東北人诞帐。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像爆雹,于是被迫代替她去往敵國和親景埃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容