詳解React Native 采用Fetch方式發(fā)送跨域POST請求
Fetch以后是趨勢,勢必要取代傳統(tǒng)的Ajax,而且RN框架支持Fetch。下面僅做了一個(gè)跨域請求的例子,在本域請求是一樣的,而且更簡單一些。客戶端環(huán)境用的是RN寫的一個(gè)頁面,也可以用瀏覽器的console控制臺(tái)模擬。后端服務(wù)用的是NodeJs express框架。
1)Fetch請求
//發(fā)送Ajax請求 sendAjax(){ //POST方式,IP為本機(jī)IP fetch("http://192.168.111.102:8085", { method: "POST", mode: "cors", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: 'key=1' }).then(function (res) { console.log("fetch request ", JSON.stringify(res.ok)); if(res.ok){ res.json().then(function (json) { console.info(json); Alert.alert('提示','來自后臺(tái)數(shù)據(jù):名字'+json.name+'、年齡'+json.age,[{text: '確定', onPress: () => console.log('OK Pressed!')},]); }); }else{ Alert.alert('提示','請求失敗',[{text: '確定', onPress: () => console.log('OK Pressed!')},]); } }).catch(function (e) { console.log("fetch fail"); Alert.alert('提示','系統(tǒng)錯(cuò)誤',[{text: '確定', onPress: () => console.log('OK Pressed!')},]); }); }
1、mode屬性控制是否允許跨域。same-origin(同源請求)、no-cors(默認(rèn))和cros(允許跨域請求),第一種跨域求情會(huì)報(bào)error,第二種可以請求其他域的腳本、圖片和其他資源,但是不能訪問response里面的屬性,第三種可以獲取第三方數(shù)據(jù),前提是所訪問的服務(wù)允許跨域訪問。否則,會(huì)出現(xiàn)如下錯(cuò)誤:
2、Fetch請求后臺(tái)時(shí),返回時(shí)一個(gè)Promise對象。對象支持解析返回?cái)?shù)據(jù)的方法有:arrayBuffer()、blob()、formData()、json()、text()。
3、Body傳入?yún)?shù),注意!注意!注意!重要的事情說三次,只能傳啊a=1&b=2...這種參數(shù)形式,不可傳對象{a:1,b:2,...},用JSON.stringify({a:1,b:2,...})也不行。在jquery中,傳入對象框架會(huì)自動(dòng)封裝成formData的形式,fetch沒有這個(gè)功能。
4、使用時(shí)請注意瀏覽器版本,低版本不支持此對象。RN是可以用的
2)Nodejs express框架開啟允許跨域請求:
//設(shè)置跨域訪問 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By",' 3.2.1'); res.header("Content-Type", "application/json;charset=utf-8"); next(); });
3)Nodejs express框架開啟處理POST數(shù)據(jù)功能,默認(rèn)POST請求的參數(shù)是在請求體里面,用res.query是獲取不到的,為{};需要使用res.body獲取,前提是要在express框架里面開啟body解析功能,否則顯示undefined。
var express = require('express'); //Post方式請求參數(shù)放在請求體里面,需引用body-parser解析body var bodyParser = require("body-parser"); var app = express(); // 引用 app.use(bodyParser.urlencoded({ extended: false }));
4)支持jsonp方式跨域訪問,開啟跨域訪問后用傳統(tǒng)的jsonp方式請求時(shí),會(huì)報(bào)錯(cuò)。因?yàn)閖sonp請求需要返回一個(gè)callback包裹的數(shù)據(jù),否則解析出錯(cuò)。此處有一個(gè)坑,用$.ajax({method:'POST',dataType:'jsonp'})方式請求時(shí),依然發(fā)送的是GET請求。
//json數(shù)據(jù) var data = { "name": "Test", "age": "19" }; app.get('/', function(req, res) { console.log('get..........'); console.log(req.query); if (req.query && req.query.callback) { var str = req.query.callback + "(" + JSON.stringify(data) + ")"; //jsonp console.log('jsonp: '+str); res.end(str); }else{ console.log('json: '+JSON.stringify(data)); res.end(JSON.stringify(data)); } });
5)完整代碼:
1、RN前端
/** * Created by linyufeng on 2016/8/22. */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, TouchableHighlight, Alert, View } from 'react-native'; class HelloWorld extends Component { //發(fā)送Ajax請求 sendAjax(){ //POST方式 fetch("http://192.168.111.102:8085", { method: "POST", mode: "cors", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: 'key=1' }).then(function (res) { console.log("fetch request ", JSON.stringify(res.ok)); if(res.ok){ res.json().then(function (json) { console.info(json); Alert.alert('提示','來自后臺(tái)數(shù)據(jù):名字'+json.name+'、年齡'+json.age,[{text: '確定', onPress: () => console.log('OK Pressed!')},]); }); }else{ Alert.alert('提示','請求失敗',[{text: '確定', onPress: () => console.log('OK Pressed!')},]); } }).catch(function (e) { console.log("fetch fail"); Alert.alert('提示','系統(tǒng)錯(cuò)誤',[{text: '確定', onPress: () => console.log('OK Pressed!')},]); }); } render() { return ( <View style={styles.container}> <TouchableHighlight style={styles.wrapper} onPress={this.sendAjax}> <View style={styles.button}> <Text>點(diǎn)擊發(fā)送Ajax請求</Text> </View> </TouchableHighlight> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, wrapper: { borderRadius: 5, marginBottom: 5, }, button: { backgroundColor: '#eeeeee', padding: 10, }, }); AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
2、NodeJs
/** * Created by linyufeng on 2016/8/22. */ var express = require('express'); //Post方式請求參數(shù)放在請求體里面,需引用body-parser解析body var bodyParser = require("body-parser"); var app = express(); // 引用 app.use(bodyParser.urlencoded({ extended: false })); //設(shè)置跨域訪問 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By",' 3.2.1'); res.header("Content-Type", "application/json;charset=utf-8"); next(); }); //json數(shù)據(jù) var data = { "name": "Test", "age": "19" }; app.get('/', function(req, res) { console.log('get..........'); console.log(req.query); if (req.query && req.query.callback) { var str = req.query.callback + "(" + JSON.stringify(data) + ")"; //jsonp console.log('jsonp: '+str); res.end(str); }else{ console.log('json: '+JSON.stringify(data)); res.end(JSON.stringify(data)); } }); app.post('/', function(req, res) { console.log('post............'); console.log(req.body); console.log('json: '+JSON.stringify(data)); res.end(JSON.stringify(data)); }); app.listen(8085, function () { console.log('Listening on port 8085...'); });
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
react-three/postprocessing庫的參數(shù)中文含義使用解析
這篇文章主要介紹了react-three/postprocessing庫的參數(shù)中文含義使用總結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05從零開始搭建webpack+react開發(fā)環(huán)境的詳細(xì)步驟
這篇文章主要介紹了從零開始搭建webpack+react開發(fā)環(huán)境的詳細(xì)步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05React實(shí)現(xiàn)倒計(jì)時(shí)功能組件
這篇文章主要為大家詳細(xì)介紹了如何通過React實(shí)現(xiàn)一個(gè)倒計(jì)時(shí)功能組件,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2023-09-09React 并發(fā)功能體驗(yàn)(前端的并發(fā)模式)
React 是由 Facebook 軟件工程師 Jordan Walke 創(chuàng)建,React 的第一個(gè)版本在七年前問世,現(xiàn)在,F(xiàn)acebook 負(fù)責(zé)維護(hù),本文給大家介紹React 并發(fā)功能體驗(yàn)前端并發(fā)模式的問題,感興趣的朋友跟隨小編一起看看吧2021-07-07React Native開發(fā)封裝Toast與加載Loading組件示例
這篇文章主要介紹了React Native開發(fā)封裝Toast與加載Loading組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09React Form組件的實(shí)現(xiàn)封裝雜談
這篇文章主要介紹了React Form組件的實(shí)現(xiàn)封裝雜談,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05React Hook useState useEffect componentD
這篇文章主要介紹了React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03React 項(xiàng)目中動(dòng)態(tài)設(shè)置環(huán)境變量
本文主要介紹了React 項(xiàng)目中動(dòng)態(tài)設(shè)置環(huán)境變量,本文將介紹兩種常用的方法,使用 dotenv 庫和通過命令行參數(shù)傳遞環(huán)境變量,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04