详解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 innerHTML 的一些问题的解决方法
Jun 22 Javascript
仿猪八戒网左下角的文字滚动效果
Oct 28 Javascript
如何使用jQUery获取选中radio对应的值(一句代码)
Jun 03 Javascript
按下回车键指向下一个位置的一个函数代码
Mar 10 Javascript
基于JavaScript代码实现随机漂浮图片广告
Jan 05 Javascript
数组Array的一些方法(总结)
Feb 17 Javascript
Vue2.0 UI框架ElementUI使用方法详解
Apr 14 Javascript
vue.js的简单自动求和计算实例
Nov 08 Javascript
JS变量提升原理与用法实例浅析
May 22 Javascript
vue使用canvas实现移动端手写签名
Sep 22 Javascript
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
Nov 10 Javascript
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
May 30 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 中dirname(_file_)讲解
2007/03/18 PHP
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
php提取字符串中网站url地址的方法
2014/12/03 PHP
PHP向socket服务器收发数据的方法
2015/01/24 PHP
PHP中curl_setopt函数用法实例分析
2015/04/16 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
window.onload 加载完毕的问题及解决方案(下)
2009/07/09 Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
Jquery进度条插件 Progress Bar小问题解决
2011/07/12 Javascript
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
js操纵dom生成下拉列表框的方法
2014/02/24 Javascript
js实现文本框中焦点在最后位置
2014/03/04 Javascript
关于onchange事件在IE和FF下的表现及解决方法
2014/03/08 Javascript
从零学JS之你需要了解的几本书
2014/05/19 Javascript
什么是Node.js?Node.js详细介绍
2014/06/01 Javascript
node.js中的http.response.write方法使用说明
2014/12/14 Javascript
js窗口关闭提示信息(兼容IE和firefox)
2015/10/23 Javascript
原生javascript实现自动更新的时间日期
2016/02/12 Javascript
浅谈JavaScript的push(),pop(),concat()方法
2016/06/03 Javascript
template.js前端模板引擎使用详解
2017/10/10 Javascript
iview在vue-cli3如何按需加载的方法
2018/10/31 Javascript
Vue学习之组件用法实例详解
2020/01/06 Javascript
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
python中实现控制小数点位数的方法
2019/01/24 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
2020/04/03 Python
python中把元组转换为namedtuple方法
2020/12/09 Python
使用CSS3的rem属性制作响应式页面布局的要点解析
2016/05/24 HTML / CSS
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
节约用水倡议书
2014/04/16 职场文书
妇联主席先进事迹
2014/05/18 职场文书
2014教师研修学习体会
2014/07/08 职场文书
golang elasticsearch Client的使用详解
2021/05/05 Golang
JavaScript文档对象模型DOM
2021/11/20 Javascript
升级 Win11 还是坚守 Win10?微软 Win11 新系统缺失功能大盘点
2022/04/05 数码科技