网络请求之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") ...
随机推荐
- 跟我一起做一个vue的小项目(九)
接下来我们进行的就是城市列表页面数据额动态渲染. 也是在mock数据,进行动态渲染 //city.json { "ret": true, "data":{ &q ...
- 删除n天前的文件或文件夹 bat批处理
@echo off @echo deleting... FORFILES /p "D:\a" /D -1 /C "cmd /c echo deleting @file . ...
- 微信小程序滚动到某个位置添加class效果。
<scroll-view scroll-y="true" style="height:100vh;" bindscrolltoupper="up ...
- poj 2115 扩展欧几里德
#include<stdio.h> #include<string.h> #define max 32 typedef long long LL; LL pow2[max+]; ...
- Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍
无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和Ins ...
- phpstudy安装好之后mysql无法启动(亲测可行)
安装好phpstudy后,Apache可以启动,Mysql无法启动. 尝试解决办法:可能是之前已经装过Mysql,要把系统服务里面的MySQL删除,留下MySQLa服务. 在cmd命令行下输入:sc ...
- MySQL语句错误及解决方案
1.group by查询错误 ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contai ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- 【CodeVS】1792 分解质因数
1792 分解质因数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题目描述 Description 编写一个把整数N分解为质因数乘积的程序. 输入描述 Inp ...
- 【JZOJ5071】【GDSOI2017第二轮模拟】奶酪 树形dp
题面 CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪. YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量. YJC和 ...