详解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 相关文章推荐
在IE下获取object(ActiveX)的Param的代码
Sep 15 Javascript
jquery中this的使用说明
Sep 06 Javascript
javascript面向对象之二 命名空间
Feb 08 Javascript
js性能优化 如何更快速加载你的JavaScript页面
Mar 17 Javascript
图片img的src不变让浏览器重新加载实现方法
Mar 29 Javascript
多种方法实现load加载完成后把图片一次性显示出来
Feb 19 Javascript
js判断页面中是否有指定控件的简单实例
Mar 04 Javascript
jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
Aug 21 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
Jun 04 Javascript
vue2利用Bus.js如何实现非父子组件通信详解
Aug 25 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
Sep 05 Javascript
解决vue+router路由跳转不起作用的一项原因
Jul 19 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
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
joomla内置的表单验证功能使用方法
2010/06/11 PHP
php错误、异常处理机制(补充)
2012/05/07 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
2015/12/07 PHP
PHP中多线程的两个实现方法
2016/10/14 PHP
PHP实现简易blog的制作
2016/10/24 PHP
php 反斜杠处理函数addslashes()和stripslashes()实例详解
2016/12/25 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
用javascript做拖动布局的思路
2008/05/31 Javascript
jquery 读取页面load get post ajax 四种方式代码写法
2011/04/02 Javascript
JavaScript移除数组内重复元素的方法
2015/03/18 Javascript
纯js实现无限空间大小的本地存储
2015/06/18 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
2016/06/21 Javascript
基于JavaScript实现轮播图代码
2016/07/14 Javascript
JS多文件上传的实例代码
2017/01/11 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
2017/12/29 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
高效jQuery选择器的5个技巧实例分析
2019/11/26 jQuery
微信小程序获取公众号文章列表及显示文章的示例代码
2020/03/10 Javascript
vue+iview使用树形控件的具体使用
2020/11/02 Javascript
如何在Vue项目中添加接口监听遮罩
2021/01/25 Vue.js
Python的Django应用程序解决AJAX跨域访问问题的方法
2016/05/31 Python
python 脚本生成随机 字母 + 数字密码功能
2018/05/26 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
python 随机森林算法及其优化详解
2019/07/11 Python
对python中UDP,socket的使用详解
2019/08/22 Python
python 字符串常用方法汇总详解
2019/09/16 Python
centos+nginx+uwsgi+Django实现IP+port访问服务器
2019/11/15 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
如何使用 Flask 做一个评论系统
2020/11/27 Python
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
11月红领巾广播稿
2014/01/17 职场文书
上班玩游戏检讨书
2014/02/07 职场文书
小学体育跳绳课教学反思
2016/02/16 职场文书
Python游戏开发实例之graphics实现AI五子棋
2021/11/01 Python