详解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 相关文章推荐
复制小说文本时出现的随机乱码的去除方法
Sep 07 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
May 29 Javascript
AngularJS入门教程之学习环境搭建
Dec 06 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
jQuery实现自动调整字体大小的方法
Jun 15 Javascript
javascript实现随机读取数组的方法
Aug 03 Javascript
jquery实现简单的banner轮播效果【实例】
Mar 30 Javascript
jQuery动态生成表格及右键菜单功能示例
Jan 13 Javascript
基于vue2的table分页组件实现方法
Mar 20 Javascript
微信小程序之swiper滑动面板用法示例
Dec 04 Javascript
js实现简单的贪吃蛇游戏
Apr 23 Javascript
关于JavaScript中异步/等待的用法与理解
Nov 18 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
PHP读取MySQL数据代码
2008/06/05 PHP
七款最流行的PHP本地服务器分享
2013/02/19 PHP
php 使用GD库为页面增加水印示例代码
2014/03/24 PHP
php正则修正符用法实例详解
2016/12/29 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
php表单处理操作
2017/11/16 PHP
javascript(jquery)利用函数修改全局变量的代码
2009/11/02 Javascript
编写高性能的JavaScript 脚本的加载与执行
2010/04/19 Javascript
js调试系列 源码定位与调试[基础篇]
2014/06/18 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
JavaScript中的标签语句用法分析
2015/02/10 Javascript
Underscore.js 1.3.3 中文注释翻译说明
2015/06/25 Javascript
浅谈jQuery中height与width
2015/07/06 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
2015/11/02 Javascript
实例讲解使用原生JavaScript处理AJAX请求的方法
2016/05/10 Javascript
在javaScript中检测数据类型的几种方式小结
2017/03/04 Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
2018/04/18 Javascript
关于vue中的ajax请求和axios包问题
2018/04/19 Javascript
vue-cli3.0 特性解读
2018/04/22 Javascript
js如何找出字符串中的最长回文串
2018/06/04 Javascript
Vue图片浏览组件v-viewer用法分析【支持旋转、缩放、翻转等操作】
2019/11/04 Javascript
[01:03]悬念揭晓 11月26日DOTA2完美盛典不见不散
2017/11/23 DOTA
Python安装官方whl包和tar.gz包的方法(推荐)
2017/06/04 Python
解决pandas read_csv 读取中文列标题文件报错的问题
2018/06/15 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
Python Flask上下文管理机制实例解析
2020/03/16 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
python操作redis数据库的三种方法
2020/09/10 Python
沪江旗下的海量优质课程平台:沪江网校
2017/11/07 全球购物
Needle & Thread官网:英国仙女品牌
2018/01/13 全球购物
西班牙多品牌鞋店连锁店:Krack
2018/11/30 全球购物
银行求职推荐信范文
2013/11/30 职场文书
领导班子四风问题对照检查材料
2014/09/27 职场文书
在教室放鞭炮的检讨书
2014/09/28 职场文书
铁人纪念馆观后感
2015/06/16 职场文书