网络请求之jsonp封装
首先介绍下jsonp原理
浏览器因为同源策略的限制,在不同源的服务器通过我们传统axios是不能直接用来请求数据的(忽略代理),而src标签则不受同源策略的影响,所以我们需要动态的创建带有src的标签让其进行数据的请求,这就是jsonp的原理,在src的URL地址末尾拼接上一个回调函数,用来接受服务器传回来的数据
前端jsonp的封装展示
//封装一个jsonp请求的函数
function query(opt) {
let str = ""
for (let key in opt) {
str += key + "=" + opt[key] + "&"
}
return str
}
//设置默认回调函数的名字
const defaultOptions = {
callbackName: "callback"
}
function jsonp(url, opt, options = defaultOptions) {
//参数解析 URL为访问的接口 opt为传播的数据 option 为接受参数的回调函数
return new Promise((resolve, reject) => {
//判断下这个?是不是存在
let index = url.indexOf("?");
url += index != -1 ? query(opt) : "?" + query(opt);
url = url + `${options.callbackName}=${options.callbackName}`;
//首先创造一个标签 带有src的
const scriptDom = document.createElement("script");
//设置其src属性
scriptDom.setAttribute("src", url);
//在window系统上创建一个回调函数用来接受数据
window[options.callbackName] = (res) => {
//在接受到了参数动态删除这个script节点和window上面的方法
delete window[options.callbackName];
document.body.removeChild(scriptDom)
//接受成功后调用resolve
if (res) {
resolve(res)
} else {
reject("服务器暂没有获取到数据")
}
}
//动态创建script标记,错误的监听
scriptDom.addEventListener('error', () => {
delete window['jsonpCallback'];
document.body.removeChild(script);
reject('服务器加载失败!');
});
document.body.append(scriptDom)
})
}
调用方式
<script>
// jsonp("http://localhost:7001/api", {
// user: "zhangsan",
// age: "18"
// }).then(res=>{
// console.log(res);
// }).catch(err=>{
// console.log((err,"失败"))
// }) jsonp(" http://localhost:3000/api", {
user: "zhangsan",
age: "18"
}).then(res => {
console.log(res);
}).catch(err => {
console.log((err, "失败"))
})
</script>
后端我们使用express和egg两款框架分别实现了接口的使用
express的代码展示
const url = require("url")
router.get("/api", (req, res, next) => {
//将script标签的src的URL请求转成对象
const opj = url.parse(req.url, true).query;
//然后原理就是调用这个回调函数来进行传参
let {
callback
} = opj;
//如果这个回调函数存在证明是jsonp请求
if (callback) {
let resault = JSON.stringify({
code: 1,
msg: "express框架传回去的参数"
});
res.send(`${callback}(${resault})`)
}
})
egg框架就不需要这么麻烦了 利用中间件可以直接出来
router.js代码
module.exports=app=>{
const {router,controller}=app;
const jsonp = app.jsonp();
router.get("/api",jsonp,controller.index.api) //注意不要写成下面这种
// const {jsonp}=app;
// router.get("/api",jsonp(),controller.index.api)
} controller/index 代码
const {Controller}=require("egg"); class Index extends Controller{
api(ctx){
//直接利用body返回就会传到jsonp的回调函数里面
ctx.body={
code:11,
type:"egg返回的jsonp请求"
}
}
} module.exports=Index;
本文GitHup地址 https://github.com/qiang-chen/cross-domain
网络请求之jsonp封装的更多相关文章
- Android项目开发全程(三)-- 项目的前期搭建、网络请求封装是怎样实现的
在前两篇博文中已经做了铺垫,下面咱们就可以用前面介绍过的内容开始做一个小项目了(项目中会用到Afinal框架,不会用Afinal的童鞋可以先看一下上一篇博文),正所谓麻雀虽小,五脏俱全,这在里我会尽量 ...
- iOS 自己封装的网络请求,json解析的类
基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求 ...
- 谈谈MVVM和链式网络请求架构
前言 前一段时间一直在学习iOS的架构.为什么呢? 公司的架构一直是MVC,当我们正式上线的时候,项目已经有了超十万行代码.主要的VC一般都有2000行代码以上. 关键是,目前版本我们只做了三分之一的 ...
- Volley网络请求框架的基本用法
备注: 本笔记是参照了 http://blog.csdn.net/ysh06201418/article/details/46443235 学习之后写下的 简介: Volley是google官网退 ...
- Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest
NSURLRequest 网络请求的关键的就是NSURLRequest类,它的实例表示了请求报文实体以及请求的缓存策略等等,各种网络框架的最终目标都是把这个对象编译成为请求报文发送出去.下面用一个实例 ...
- Flutter之网络请求
Flutter之网络请求 一,介绍与需求 1.1,介绍 1,http一个可组合的,基于Future的库,用于发出HTTP请求.包含一组高级功能和类,可轻松使用HTTP资源.它与平台无关,可以在命令行和 ...
- 学习RxJava+Retrofit+OkHttp+MVP的网络请求使用
公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了. 我在网上找了很多文章,写的都很详细,比如 https://www.jianshu.com/u/5fd2523645da https://www. ...
- 2020,最新APP重构:网络请求框架
在现在的app,网络请求是一个很重要的部分,app中很多部分都有或多或少的网络请求,所以在一个项目重构时,我会选择网络请求框架作为我重构的起点.在这篇文章中我所提出的架构,并不是所谓的 最好 的网络请 ...
- 关于ajax网络请求的封装
// 封装的ajax网络请求函数// obj 是一个对象function AJAX(obj){ //跨域请求 if (obj.dataType == "jsonp") ...
随机推荐
- 【python之路28】模块python与excel
一.可使用的第三方库 python中处理excel表格,常用的库有xlrd(读excel)表.xlwt(写excel)表.openpyxl(可读写excel表)等.xlrd读数据较大的excel表时效 ...
- Django项目:CRM(客户关系管理系统)--53--44PerfectCRM实现账号快速注册登陆
# gbacc_ajax_urls.py # ————————42PerfectCRM实现AJAX全局账号注册———————— from django.conf.urls import url fro ...
- bzoj 1800 [Ahoi2009]fly 飞行棋——模拟
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1800 原来只想到一个弧是一条边. 然后发现不是.差点不会做.经Zinn提醒,不用枚举那条边由 ...
- js中的定义变量之①用不用var
var 是js定义变量的意思. 由于js中的变量是弱类型的,因此js中的所有变量包括number(数字型).string(字符串类型).boolean(布尔类型,true和false)等均通过var关 ...
- 玩转webpack之webpack的基本知识
相信看了gulp教程的小伙伴肯定都可以很容易的掌握gulp了.它已经没有什么可以值得去思考的东西了,如果你已经看懂它就是单纯的在布置任务,然后利用插件的功能去执行任务.最后发布任务,pipe的理念来和 ...
- git图形化
在windows下安装git中文版客户端并连接gitlab 转载自:https://blog.whsir.com/post-1801.html 下载git Windows客户端 git客户端下载地址: ...
- 访问者模式(Visitor、Element、accept、ObjectStructure、)(操作外置,与数据结构分离)
访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作.从定义可以看出结构对象是使用访问者模式的必备条件,而且这个结构对象必须存在遍历自身各个 ...
- python 读取xml文件
首先,获得标签信息abc.xml <?xml version="1.0" encoding="utf-8"?> <catalog> &l ...
- sar磁盘I/O统计数据
sar是一个研究磁盘I/O的优秀工具.以下是sar磁盘I/O输出的一个示例. 第一行-d显示磁盘I/O信息,5 2选项是间隔和迭代,就像sar数据收集器那样.表3-3列出了字段和说明. 表3-3 ...
- WordPress资料收集,以后整理
WordPress主题开发:实现分页功能 http://www.cnblogs.com/tinyphp/p/6361901.html WordPress如何调取显示指定文章 https://www.d ...