首先介绍下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封装的更多相关文章

  1. Android项目开发全程(三)-- 项目的前期搭建、网络请求封装是怎样实现的

    在前两篇博文中已经做了铺垫,下面咱们就可以用前面介绍过的内容开始做一个小项目了(项目中会用到Afinal框架,不会用Afinal的童鞋可以先看一下上一篇博文),正所谓麻雀虽小,五脏俱全,这在里我会尽量 ...

  2. iOS 自己封装的网络请求,json解析的类

    基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求 ...

  3. 谈谈MVVM和链式网络请求架构

    前言 前一段时间一直在学习iOS的架构.为什么呢? 公司的架构一直是MVC,当我们正式上线的时候,项目已经有了超十万行代码.主要的VC一般都有2000行代码以上. 关键是,目前版本我们只做了三分之一的 ...

  4. Volley网络请求框架的基本用法

    备注: 本笔记是参照了 http://blog.csdn.net/ysh06201418/article/details/46443235  学习之后写下的 简介:  Volley是google官网退 ...

  5. Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest

    NSURLRequest 网络请求的关键的就是NSURLRequest类,它的实例表示了请求报文实体以及请求的缓存策略等等,各种网络框架的最终目标都是把这个对象编译成为请求报文发送出去.下面用一个实例 ...

  6. Flutter之网络请求

    Flutter之网络请求 一,介绍与需求 1.1,介绍 1,http一个可组合的,基于Future的库,用于发出HTTP请求.包含一组高级功能和类,可轻松使用HTTP资源.它与平台无关,可以在命令行和 ...

  7. 学习RxJava+Retrofit+OkHttp+MVP的网络请求使用

    公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了. 我在网上找了很多文章,写的都很详细,比如 https://www.jianshu.com/u/5fd2523645da https://www. ...

  8. 2020,最新APP重构:网络请求框架

    在现在的app,网络请求是一个很重要的部分,app中很多部分都有或多或少的网络请求,所以在一个项目重构时,我会选择网络请求框架作为我重构的起点.在这篇文章中我所提出的架构,并不是所谓的 最好 的网络请 ...

  9. 关于ajax网络请求的封装

    // 封装的ajax网络请求函数// obj 是一个对象function AJAX(obj){ //跨域请求        if (obj.dataType == "jsonp") ...

随机推荐

  1. LA5713 Qin Shi Huang's National Road System

    题目大意:秦始皇要在n个城市之间修筑一条道路使得任意两个城市均可连通.有个道士可以用法力帮忙修一条路.秦始皇希望其他的道路总长B最短且用法术连接的两个城市的人口之和A尽量大,因此下令寻找一个A / B ...

  2. return语句必须要注意的地方

    先看下面程序: function foo1() { return { /*返回对象{}他留有一个大括号跟return在同一行*/ bar: "hello" }; } functio ...

  3. Lab2 内存管理(实现细节)

    lab2 中的变动 bootloader 的入口发生了改变 bootloader不像lab1那样,直接调用kern_init函数,而是先调用位于lab2/kern/init/entry.S中的kern ...

  4. 【P1203】 【USACO1.1】坏掉的项链Broken Necklace

    P1203 [USACO1.1]坏掉的项链Broken Necklace 题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 ...

  5. Liferay 7:如何在Liferay Portlet中使用Angular, React, Vue.js等前端框架

    https://web.liferay.com/zh/web/ivan.zaera/blog/-/blogs/modern-frontend-workflows-in-liferay-portal L ...

  6. 微服务开源生态报告 No.8

    「微服务开源生态报告」,汇集各个开源项目近期的社区动态,帮助开发者们更高效的了解到各开源项目的最新进展. 社区动态包括,但不限于:版本发布.人员动态.项目动态和规划.培训和活动. 非常欢迎国内其他微服 ...

  7. QT_获取运行进程所在目录路径_1

    QString getProcessPathForWin(int idProcess) { #ifdef Q_OS_WIN // access process path WCHAR name[]; Z ...

  8. web前端学习(四)JavaScript学习笔记部分(2)-- JavaScript语法详解

    2.1.Javascript语法-运算符(1) 复数运算符 %取余 ++ -- 赋值运算符 += -= *= /= %= 字符串操作 <!DOCTYPE html> <html la ...

  9. python设计模式整理

    设计模式的定义:为了解决面向对象系统中重要和重复的设计封装在一起的一种代码实现框架,可以使得代码更加易于扩展和调用 四个基本要素:模式名称,问题,解决方案,效果 六大原则: 1.开闭原则:一个软件实体 ...

  10. 虚幻UE4的后处理特效介绍 http://www.52vr.com/thread-31215-1-1.html

    转载 虚幻UE4提供了后处理特效的功能,可以实现景深,光溢出,色调调整,饱和度等等.要使用虚幻4的后处理,就一定要用到PostProcessVolumn,这是一种特殊的体积,可以放置在场景中的任何位置 ...