手把手教你实现一个通用的jsonp跨域方法
什么是jsonp
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
以上内容来自百度,不太理解不要紧,记住最重要的一点是:通过script标签引入的链接,接口返回的内容是被当成js代码来进行解析的。请大家记住这一点,很重要的特性。
创建一个简单的jsonp服务器
下面是一个基于nodejs的简单的服务器,如果不了解nodejs也没关系,大家看下注释,理解下作用就可以
const http = require('http')
const url = require('url')
const jsonpServer = http.createServer((req, res) => {
let data = {
status: true,
msg: 'hello jsonp'
}
const body = url.parse(req.url, true)
// jsonp请求中会包含一个callback参数,例如 http://baidu.com.js?callback=hello
// 获取请求的url中的callback参数的值,callback是一个函数名
const callback = body.query.callback
// 将对象数据转为字符串
data = JSON.stringify(data)
// 拼接成js代码
// 举个例子,假设这个callback回调的名字是 test
// 拼接完就是 test({status: true,msg: 'hello jsonp'})
// 显然,就是一段js代码,作用就是执行这个函数
const js = `${callback}(${data})`
// 返回js代码给客户端
res.end(js)
})
jsonpServer.listen('3000', (err) => {
if (!err) {
console.log('server is running at localhost:3000')
}
})
创建完服务器以后,我们接下来开始书写一个jsonp
/**
* @description 创建一个随机的函数名
* @return {string}
*/
const createCallbackName = function () {
return `callback${(Math.random() * 1000000).toFixed(0)}`
}
/**
* @description 插入一个script标签
* @param url {string}
*/
const insertScript = function (url) {
let script = document.createElement('script')
script.onload = script.onerror = function () {
document.body.removeChild(script)
}
script.setAttribute('src', url)
document.body.appendChild(script)
}
/**
* @description 拼接字符串参数
* @param url {string} url
* @param data {object} 要拼接的query数据
* @return url {string} 拼接完成后的新url
*/
const setQuery = function (url, data) {
const keys = Object.keys(data)
if (keys.length === 0) {
return url
} else{
const pairs = keys.map(key => `${key}=${data[key]}`)
url = url.includes('?') ? url : `${url}?`
url += pairs.join('&')
return url
}
}
/**
* @description jsonp函数
* @param url {string} 请求地址
* @param config {object} 接口配置设置
* @return {Promise}
*/
const jsonp = function (url, config = {}) {
let data = config.data || {}
let timeout = config.timeout || 5000
let timer
const funcName = createCallbackName()
data.callback = funcName
return new Promise((resolve, reject) => {
window[funcName] = function (res) {
if (timer) {
clearTimeout(timer)
}
delete window[funcName]
resolve(res)
}
url = setQuery(url, data)
timer = setTimeout(() => {
delete window[funcName]
reject(new Error(`fetch ${url} fail`))
}, timeout)
insertScript(url)
})
}
// 使用效果
jsonp('http://localhost:3000')
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})

项目演示地址请查看github: jsonp
来源:https://segmentfault.com/a/1190000015942144
手把手教你实现一个通用的jsonp跨域方法的更多相关文章
- Angular4 后台管理系统搭建(10) - 做一个通用的可跨域上传文件的组件
写的很慢,不知不觉这是第十篇了.但是我其他事情太多,只能抽空写下.现在angular4或angular2流行的上传方式是ng2-file-upload.它的功能很强大.但是我没有配置成可以跨域上传的. ...
- 深入剖析jsonp跨域原理
在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域的原理.搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求: 2)jsonp跨域的 ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- PWA入门:手把手教你制作一个PWA应用
摘要: PWA图文教程 原文:PWA入门:手把手教你制作一个PWA应用 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 简介 Web前端的同学是否想过学习app开发,以弥补自 ...
- R数据分析:跟随top期刊手把手教你做一个临床预测模型
临床预测模型也是大家比较感兴趣的,今天就带着大家看一篇临床预测模型的文章,并且用一个例子给大家过一遍做法. 这篇文章来自护理领域顶级期刊的文章,文章名在下面 Ballesta-Castillejos ...
- 关于前端jsonp跨域和一个简单的node服务搭建
先讲下概念 同源策略:是一种约定,浏览器最核心最基本的安全功能,(同域名,同协议,同端口)为同源 跨域: 跨(跳):范围 域 (源):域名,协议,端口 域名:ip的一种昵称(为了更好记住ip地址)如: ...
- jsonp跨域 封装通用方法
jsonp跨域 封装通用方法 //用法如下 jsonp({ url:"https://www.xxxx.com", params:{wd:'b'}, callback:'show' ...
- 通用jsonp跨域技术获取天气数据
1. 前言 在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题可以使用jsonp技术 2.代码 <!DOCT ...
随机推荐
- PKU 百练OJ Arbitrage
http://bailian.openjudge.cn/practice/2240/ #include <iostream> #include <string> #includ ...
- 最小费用最大流——ZKW
对于最小费用最大流,我们的通常做法是EK+SPFA. 然而,卡常界大佬ZKW发明了一个求解最小费用最大流的方法,很强啊. 在学ZKW费用流前,先说说KM算法. KM算法 为啥要先提这个呢?因为ZKW费 ...
- 廖雪峰Java10加密与安全-4加密算法-5非对称加密算法
1.非对称加密 非对称加密就是加密和解密使用的不是相同的密钥 方法1: * 加密:用自己的私钥加密,然后发送给对方:encrypt(privateKeyA, message)->s * 解密:对 ...
- MySQL系列(十一)--外键约束foreign key的基本使用
有些时候,为了保证数据的完整性,我们会选择的使用外键约束,例如教师对应的表和课程表中老师的id,这种时候就要使用外键约束了. PS:这里不考虑表结构设计,三范式与反范式等设计问题,基于MySQL8.0 ...
- php循环语句(一)
PHP 循环语句 什么是循环语句? 在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句.一组被重复执行的语句称之为循环体,能否继续重复,决定循环的终止条件.循环结构是在一定 ...
- 《Python机器学习及实践:从零开始通往Kaggle竞赛之路》
<Python 机器学习及实践–从零开始通往kaggle竞赛之路>很基础 主要介绍了Scikit-learn,顺带介绍了pandas.numpy.matplotlib.scipy. 本书代 ...
- 组件:参数验证props:组件参数验证语法
<!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...
- Trie性能分析之敏感词过滤golang
package util import ( "strings" ) type Node struct { //rune表示一个utf8字符 char rune Data inter ...
- Linux内核源码真是个好东西
我突然发现,我是这么爱Linux内核源码.... 真幸福死了.... int vsprintf(char *buf, const char *fmt, va_list args) 这函数的实现 ...
- 利用TensorFlow识别手写的数字---基于两层卷积网络
1 为什么使用卷积神经网络 Softmax回归是一个比较简单的模型,预测的准确率在91%左右,而使用卷积神经网络将预测的准确率提高到99%. 2 卷积网络的流程 3 代码展示 # -*- coding ...