摘要:內置了三種發送網絡請求的方式和。轉換二進制為發送到目前為止,不能發送非序列化的數據,所以,要發送二進制數據,采用編碼的字符串是個不錯的選擇。在最新版本的層也已經支持協議來傳輸二進制文件,但是,相應的原生平臺的網絡模塊暫時還不支持。
端)
本文原創,轉載請注明作者及出處
在使用React Native開發中,我們熟練的采用JavaScript的方式發送請求的方式發送一個請求到服務端,但是處理這個請求的過程其實和處理Web應用中發送的請求的過程是不一樣的。因為處理這個請求的目標不是瀏覽器,而是嵌入這個應用的原生操作系統。
在處理React Native的請求時,分為兩部分:一部分是JavaScript的運行環境,另一部分是嵌入JavaScript的Native(即原生Android和IOS)運行環境。React Native內置了三種發送網絡請求的方式:fetch, XMLHttpRequest 和 WebSocket。但是React Native的運行環境和Web應用的運行環境不一樣,所以需要在原生應用層采用自定義函數來拓展運行時(runtime)環境來處理JavaScript發出的網絡請求。
請求發送方式及過程對于常用的網絡請求對象:XMLHttpRequest(XHR)、Fetch及WebSocket,熟悉前端開發的同學應該非常了解。XHR是Web開發中用得比較多的發送請求的方式,Fetch和Websocket也是后起之秀,在很多現代Web應用中得以采用。但是,在React Native中,這些對象的使用和Web應用是有差別的。當你在JS層調用網絡請求時,其實是經歷了兩個過程才到達真正的服務器端。就像頭部banner表示的那樣。
XMLHttpRequest(XHR)在React Native中, XMLHttpRequest(XHR)由兩部分組成: “前端”(front-end)和“后端”(back-end)。前端負責與JavaScript交互,后端負責在原生平臺上轉換JavaScript發送過來的請求為原生系統自己的請求。
這里的后端其實是一個原生平臺頂層抽象的統一API層,使得JavaScript層可以調用原先系統的網絡模塊。例如IOS下內置的URLSession模塊和Android下的OKHTTP模塊。
Fetch在現代Web瀏覽器中,FetchAPI提供了和XHR大部分相同的功能,但是Fetch提供了一種更加簡單,高效的方式來跨網絡異步獲取資源,同時可操縱Request和Response對象來復用請求。
但是在React Native中,為了兼容兩種平臺的差異,采用了依賴于XMLHttpRequest的Fetch Polyfill來實現這個請求對象。這就意味著我們不能像實用Web平臺下的Fetch對象一樣來實用React Native下的該對象。比如采用這個對象來發送binary數據。當然可以采用第三方的庫比如react-native-fetch-blob來實現相應的功能。
WebsocketWebsocket作為一種新的通信協議,采用全雙工通訊方式與服務器間進行通信的網絡技術。
在React Native中,Websocket并不是一個獨立的請求,和XMLHttpRequest(XHR)一樣由兩部分組成: “前端”(front-end)和“后端”(back-end)。前端負責與JavaScript交互,后端負責在原生平臺上轉換JavaScript發送過來的請求為原生系統自己的請求。在IOS中采用的是自己開發的NSStream,而在Android系統中則是OKHTTP模塊。
查看React Native中的網絡請求在React Native開發中,你可以通過Chrome Developer Tools (CDT)的Sources面板中調試javascript部分的代碼,包括斷點、輸出信息、斷點調試等一切javascript調試所需的信息。但是,唯一缺少的就是網絡請求的跟蹤調試。我們沒辦法像Web開發那樣,可以通過CDT中的網絡面板(Network)來查看應用的網絡請求的相關信息。
使用代理調試網絡請求雖然沒有辦法通過CDT查看應用的網絡請求,但是我們可以通過Fiddler、CharlesProxy及Wireshark等軟件設置代理,來查看追蹤調試網絡請求。這里使用Fiddler來作為代理。
首先設置Fiddler的代理端口:
打開Filddler -> Tool -> Options -> Connects,在監聽端口處填寫相應的端口號,
在調試機器上、Android或者IOS模擬器模擬器中設置代理:
找到調試的機器上的網絡設置中,設置當前連接的WIFI的代理地址
刷新應用,在fiddler中查看網絡請求(提示:右鍵,在新頁簽中打開可查看清晰圖片):
看請求頭,返回頭,返回結果等相關的網絡信息。當然,還可以根據相關代理軟件攔截請求,重新設置后發送。
使用Reactotron調試網絡上面通過設置代理的方式來查看和追蹤網絡請求,雖然功能強大,但是實際操作起來有些難度,上手成本比較高。通過使用Reactotron,可以將調試的配置信息集成到應用中,方便在不同的開發環境下有相同的調試配置,節約開發配置成本。
Reactotron由兩部分組成,一部分是調試應用,一部分是調試配置。
調試應用分別有各個操作系統的GUI安裝版本。當然,如果習慣使用命令行,也可以使用NPM安裝reactotron-cli
npm install -g reactotron-cli
設置調試配置:
在你的React Native應用中安裝reactotron-react-native
npm i --save-dev reactotron-react-native
然后,在你的應用的添加配置文件,定制調試內容: ``` import Reactotron, { trackGlobalErrors, openInEditor, overlay, asyncStorage, networking } from "reactotron-react-native" Reactotron .configure({ name: "xxx" // 調試的名稱 }) .use(trackGlobalErrors()) // 設置監聽全局錯誤 .use(openInEditor()) // 設置在編輯器中打開錯誤 .use(overlay()) // 設置圖片遮蓋圖片(用于UI還原度對比) .use(asyncStorage()) // 設置異步存儲調試 .use(networking()) // 設置網絡調試 .connect() // 連接應用(必須) ``` 然后在你的應用的入口文件中引入這個配置文件。然后重新啟動應用。當然,還可以使用正則表達式過濾請求的`contentType`的類型和要忽略的請求的`url`,見下面的配置: ``` .use(networking({ ignoreContentTypes: /^(image)/.*$/i, // 設置reactotron要忽略的文件類型 ignoreUrls: //(logs|symbolicate)$/, // 設置reactotron要忽略的url請求路徑 })) ```
![reactotron設置]
reactotron調試網絡只是他的一個功能之一,其他還有很多強大的功能。有興趣可以查看他的文檔。
使用Chrome Developer Tools網絡面板調試網絡React Native默認暴露出來的接口中,是沒有直接在Chrome Developer Tools查看網絡請求的方法的,查看 RN 源碼 Libraries/Core/InitializeCore.js,注釋中寫著:
Sets an object’s property. If a property with the same name exists, this will
replace it but maintain its descriptor configuration. By default, the property
will replaced with a lazy getter.
*
The original property value will be preserved as original[PropertyName] so
that, if necessary, it can be restored. For example, if you want to route
network requests through DevTools (to trace them):
*
global.XMLHttpRequest = global.originalXMLHttpRequest;
*
@see https://github.com/facebook/r...
具體實現在XHRInterceptor.js中。原來的XMLHttpRequest 被改寫成了 originalXMLHttpRequest,所以要在Chrome 中顯示network 只需要替換 XMLHttpRequest 為 originalXMLHttpRequest。在入口文件處設置:
if (__DEV__) { GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest }
當然,這樣有可能會產生CORS, Chrome 會限制跨域請求。這時要么后端配合一下去除限制,要么使用 Allow-Control-Allow-Origin: * 插件。
React Native發送二進制數據(binary data )由于React Native中Fetch對象的底層采用的是XHR實現,這就限制了發送二進制數據的功能。當然React Native提供了一系列的方式來解決這個問題,比如: 轉換二進制文件為base64字符串或者采用第三方庫 react-native-fetch-blob。但是并沒有從底層解決這個問題。
轉換二進制為base64發送到目前為止,React Native不能發送非序列化的數據,所以,要發送二進制數據,采用Base64編碼的字符串是個不錯的選擇。
例如,你從服務器下載一張圖片(注意:不是通過url從服務器獲取),請求通過JavaScript線程,再通過React Native提供的橋接器,最后通過原生系統的網絡模塊發送到服務端。服務端返回一個Base64編碼過的圖片,JavaScript線程收到返回的字符串后,會分配相應的內存,然后React Native會調用相應的原生模塊渲染成相應圖片。但是值得主要的是,這種方式會造成典型的性能問題——內存泄漏。
通過Base64編碼的方式傳輸二進制文件,這里會造成一系列性能問題,這篇文章中列出了大部分性能問題及提出了相應的解決方案。
現在使用的各種方法發送二進制文件都存在各種問題,最終的解決方式是要相應的標準能夠實現二進制的傳輸。目前,WebSocket已經支持了二進制傳輸。在最新版本的React Native層也已經支持WebSocket協議來傳輸二進制文件,但是,相應的原生平臺的網絡模塊暫時還不支持。
總結React Native開發方式是非常不錯的體驗,但是,受各個平臺差異和標準的限制,不得不折中處理一些問題。隨之而來的是相應的性能、效率的問題。另外,采用開發,性能上和用戶體驗上和原生應用還是有一定差距。但是如果在原生應用中能夠集成React Native,會顯著提高開發效率。
參考Network layer in React Native
reactotron介紹
reactotron
Reactotron on React Native
推薦: 翻譯項目Master的自述: 1. 干貨|人人都是翻譯項目的Master 2. iKcamp出品微信小程序教學共5章16小節匯總(含視頻) 3. 開始免費連載啦~每周2更共11堂iKcamp課|基于Koa2搭建Node.js實戰項目教學(含視頻)| 課程大綱介紹文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92589.html
閱讀 2312·2021-11-17 09:33
閱讀 843·2021-10-13 09:40
閱讀 574·2019-08-30 15:54
閱讀 778·2019-08-29 15:38
閱讀 2417·2019-08-28 18:15
閱讀 2475·2019-08-26 13:38
閱讀 1842·2019-08-26 13:36
閱讀 2129·2019-08-26 11:36