详解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...'); });
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。