本文主要介紹了詳解React Native 採用Fetch方式發送跨域POST請求,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。
Fetch以後是趨勢,勢必要取代傳統的Ajax,而且RN框架支援Fetch。下面僅做了一個跨域請求的例子,在本域請求是一樣的,而且更簡單一些。客戶端環境用的是RN寫的一個頁面,也可以用瀏覽器的console控制台模擬。後端服務用的是NodeJs express框架。
1)Fetch請求
//发送Ajax请求 sendAjax(){ //POST方式,IP为本机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('提示','来自后台数据:名字'+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('提示','系统错误',[{text: '确定', onPress: () => console.log('OK Pressed!')},]); }); }
1、mode屬性控制是否允許跨域。 same-origin(同源請求)、no-cors(預設)和cros(允許跨域請求),第一種跨域求情會報error,第二種可以請求其他域的腳本、圖片和其他資源,但是不能存取response裡面的屬性,第三種可以取得第三方數據,前提是所存取的服務允許跨網域存取。否則,會出現以下錯誤:
2、Fetch請求後台時,傳回時一個Promise物件。物件支援解析回傳資料的方法有:arrayBuffer()、blob()、formData()、json()、text()。
3、Body傳入參數,注意!注意!注意!重要的事情說三次,只能傳啊a=1&b=2...這種參數形式,不可傳物件{a:1,b:2,...},用JSON.stringify({a:1, b:2,...})也不行。在jquery中,傳入物件框架會自動封裝成formData的形式,fetch沒有這個功能。
4、使用時請注意瀏覽器版本,低版本不支援此物件。 RN是可以用的
2)Nodejs express框架開啟允許跨域請求:
//设置跨域访问 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數據功能,預設POST請求的參數是在請求體裡面,用res.query是取得不到的,為{};需要使用res.body獲取,前提是要在express框架裡面開啟body解析功能,否則顯示undefined。
var express = require('express'); //Post方式请求参数放在请求体里面,需引用body-parser解析body var bodyParser = require("body-parser"); var app = express(); // 引用 app.use(bodyParser.urlencoded({ extended: false }));
4)支援jsonp方式跨域訪問,開啟跨域訪問後用傳統的jsonp方式請求時,會報錯。因為jsonp請求需要傳回一個callback包裹的數據,否則解析出錯。這裡有一個坑,用$.ajax({method:'POST',dataType:'jsonp'})方式請求時,依然發送的是GET請求。
//json数据 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 { //发送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('提示','来自后台数据:名字'+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('提示','系统错误',[{text: '确定', onPress: () => console.log('OK Pressed!')},]); }); } render() { return ( <View style={styles.container}> <TouchableHighlight style={styles.wrapper} onPress={this.sendAjax}> <View style={styles.button}> <Text>点击发送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方式请求参数放在请求体里面,需引用body-parser解析body var bodyParser = require("body-parser"); var app = express(); // 引用 app.use(bodyParser.urlencoded({ extended: false })); //设置跨域访问 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数据 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...'); });
相關推薦:
#vue resource post請求時遇到的問題解決方法
#以上是React Native 採用Fetch方式發送POST請求的詳細內容。更多資訊請關注PHP中文網其他相關文章!