详解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 相关文章推荐
js小技巧--自动隐藏红叉叉
Aug 13 Javascript
Javascript 获取LI里的内容
Dec 17 Javascript
超简单的jquery的AJAX用法
May 10 Javascript
jQuery实现点击文本框弹出热门标签的提示效果
Nov 17 Javascript
IE中JS跳转丢失referrer问题的2个解决方法
Jul 18 Javascript
js获取隐藏元素宽高的实现方法
May 19 Javascript
jquery模拟多级复选框效果的简单实例
Jun 08 Javascript
实例讲解JavaScript中的this指向错误解决方法
Jun 13 Javascript
Vue-resource实现ajax请求和跨域请求示例
Feb 23 Javascript
seajs模块压缩问题与解决方法实例分析
Oct 10 Javascript
Node.js API详解之 assert模块用法实例分析
May 26 Javascript
vue使用video插件vue-video-player详解
Oct 23 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字符串截取问题
2006/11/28 PHP
Zend 输出产生XML解析错误
2009/03/03 PHP
来自phpguru得Php Cache类源码
2010/04/15 PHP
php中如何同时使用session和cookie来保存用户登录信息
2013/07/05 PHP
PHP编程风格规范分享
2014/01/15 PHP
PHP explode()函数的几个应用和implode()函数有什么区别
2015/11/05 PHP
PHP用mysql_insert_id()函数获得刚插入数据或当前发布文章的ID
2016/11/25 PHP
PhpStorm 2020.3:新增开箱即用的PHP 8属性(推荐)
2020/10/30 PHP
jquery中.add()的使用分析
2013/04/26 Javascript
Iframe 自动适应页面的高度示例代码
2014/02/26 Javascript
jquery解析JSON数据示例代码
2014/03/17 Javascript
JavaScript将当前时间转换成UTC标准时间的方法
2015/04/06 Javascript
jquery实现手风琴效果
2015/11/20 Javascript
jQuery动画效果相关方法实例分析
2015/12/31 Javascript
获取阴历(农历)和当前日期的js代码
2016/02/15 Javascript
Vue.js 插件开发详解
2017/03/29 Javascript
使用jQuery,Angular实现登录界面验证码详解
2017/04/27 jQuery
js Date()日期函数浏览器兼容问题解决方法
2017/09/12 Javascript
js Dom实现换肤效果
2017/10/21 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
2018/09/20 Javascript
微信小程序之事件交互操作实例分析
2018/12/03 Javascript
微信小程序实现多个按钮的颜色状态转换
2019/02/15 Javascript
ES6 Array常用扩展的应用实例分析
2019/06/26 Javascript
谈谈node.js中的模块系统
2020/09/01 Javascript
Python的ORM框架SQLAlchemy入门教程
2014/04/28 Python
Python爬虫实例扒取2345天气预报
2018/03/04 Python
浅谈pyqt5在QMainWindow中布局的问题
2019/06/21 Python
python爬虫 模拟登录人人网过程解析
2019/07/31 Python
numpy求平均值的维度设定的例子
2019/08/24 Python
波兰香水和化妆品购物网站:Notino.pl
2017/11/07 全球购物
一道SQL面试题
2012/12/31 面试题
大四学生思想汇报
2014/01/13 职场文书
生产部岗位职责范文
2014/02/07 职场文书
在宿舍喝酒的检讨书
2014/09/28 职场文书
教师教育心得体会
2016/01/19 职场文书
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
2021/06/30 SQL Server