详解React Native 采用Fetch方式发送跨域POST请求


Posted in Javascript onNovember 15, 2017

Fetch以后是趋势,势必要取代传统的Ajax,而且RN框架支持Fetch。下面仅做了一个跨域请求的例子,在本域请求是一样的,而且更简单一些。客户端环境用的是RN写的一个页面,也可以用浏览器的console控制台模拟。后端服务用的是NodeJs express框架。

详解React Native 采用Fetch方式发送跨域POST请求

详解React Native 采用Fetch方式发送跨域POST请求

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里面的属性,第三种可以获取第三方数据,前提是所访问的服务允许跨域访问。否则,会出现如下错误:

详解React Native 采用Fetch方式发送跨域POST请求

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...');
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery的实现原理的模拟代码 -1 核心部分
Aug 01 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
Nov 21 Javascript
jQuery :nth-child前有无空格的区别分析
Jul 11 Javascript
js网页中的(运行代码)功能实现思路
Feb 04 Javascript
jquery实现微博文字输入框 输入时显示输入字数 效果实现
Jul 12 Javascript
Jquery焦点图实例代码
Nov 25 Javascript
js实现仿京东2级菜单效果(带延时功能)
Aug 27 Javascript
使用ionic(选项卡栏tab) icon(图标) ionic上拉菜单(ActionSheet) 实现通讯录界面切换实例代码
Oct 20 Javascript
基于滚动条位置判断的简单实例
Dec 14 Javascript
angular1.x ui-route传参的三种写法小结
Aug 31 Javascript
Koa代理Http请求的示例代码
Oct 10 Javascript
Angular Material Icon使用详解
Nov 07 Javascript
bootstrap 通过加减按钮实现输入框组功能
Nov 15 #Javascript
layui框架中layer父子页面交互的方法分析
Nov 15 #Javascript
layer实现关闭弹出层刷新父界面功能详解
Nov 15 #Javascript
layui.js实现的表单验证功能示例
Nov 15 #Javascript
javascript函数的节流[throttle]与防抖[debounce]
Nov 15 #Javascript
基于jQuery实现定位导航位置效果
Nov 15 #jQuery
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 #Javascript
You might like
PHP 替换模板变量实现步骤
2009/08/24 PHP
Ha0k 0.3 PHP 网页木马修改版
2009/10/11 PHP
php生成圆角图片的方法
2015/04/07 PHP
PHP合并discuz用户脚本的方法
2015/08/04 PHP
php时间戳转换代码详解
2019/08/04 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
通过百度地图获取公交线路的站点坐标的js代码
2012/05/11 Javascript
Jquery选择子控件&quot;大于号&quot;和&quot; &quot;区别介绍及使用示例
2013/06/25 Javascript
使用js 设置url参数
2013/07/08 Javascript
JS批量操作CSS属性详细解析
2013/12/16 Javascript
JavaScript中Object.prototype.toString方法的原理
2016/02/24 Javascript
jQuery web 组件 后台日历价格、库存设置的代码
2016/10/14 Javascript
jQuery Ajax全解析
2017/02/13 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
2017/12/11 jQuery
使用Angular-CLI构建NPM包的方法
2018/09/07 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
2018/12/03 Javascript
深入了解响应式React Native Echarts组件
2019/05/29 Javascript
javascript之分片上传,断点续传的实际项目实现详解
2019/09/05 Javascript
微信小程序 搜索框组件代码实例
2019/09/06 Javascript
javascript贪吃蛇游戏设计与实现
2020/09/17 Javascript
python开发简易版在线音乐播放器
2017/03/03 Python
python中闭包Closure函数作为返回值的方法示例
2017/12/17 Python
安装python时MySQLdb报错的问题描述及解决方法
2018/03/20 Python
python设置值及NaN值处理方法
2018/07/03 Python
Python利用神经网络解决非线性回归问题实例详解
2019/07/19 Python
python 使用shutil复制图片的例子
2019/12/13 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
接口可以包含哪些成员
2012/09/30 面试题
思想品德自我鉴定
2013/10/12 职场文书
课程设计心得体会
2013/12/28 职场文书
学校门卫岗位职责
2014/03/16 职场文书
2015年五一劳动节活动总结
2015/02/09 职场文书
解决 redis 无法远程连接
2022/05/15 Redis
MySQL存储过程及语法详解
2022/08/05 MySQL