什么是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) =&gt; {
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) =&gt; {
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 =&gt; `${key}=${data[key]}`)
url = url.includes('?') ? url : `${url}?`
url += pairs.join('&amp;')
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) =&gt; {
window[funcName] = function (res) {
if (timer) {
clearTimeout(timer)
}
delete window[funcName]
resolve(res)
}
url = setQuery(url, data)
timer = setTimeout(() =&gt; {
delete window[funcName]
reject(new Error(`fetch ${url} fail`))
}, timeout)
insertScript(url)
})
}
// 使用效果
jsonp('http://localhost:3000')
.then(res =&gt; {
console.log(res)
})
.catch(err =&gt; {
console.log(err)
})

项目演示地址请查看github: jsonp

来源:https://segmentfault.com/a/1190000015942144

最新文章

  1. 将Json数据转换为ADO.NET DataSet对象
  2. mac上如何卸载oracle jdk 1.7
  3. BQ27510 电量计的校准 的 C语言实现
  4. [转】:HTTP请求流程(一)----流程简介
  5. bzoj 3033 太鼓达人
  6. ActiveMQ基本配置与示例演示
  7. yzoi1109&amp;&amp;viojs1042最小步数的一点看法——回文数
  8. h.264 fast,1/2,1/4像素运动估计与插值处理
  9. C#识别图片上的数字
  10. DirectFB 之 环境配置
  11. Android源码解析——AsyncTask
  12. Pandas-数据的合并与拼接
  13. Open Distro for Elasticsearch – How Different Is It?
  14. vue-cli sass安装
  15. 极限编程核心价值:沟通(Communication)
  16. [GIt] 团队工作效率分析工具gitstats
  17. Objective-C:继承的体现
  18. 07.centos7构建 IntelliJ IDEA(简称IDEA)开发环境
  19. Integer判断相等,到底该用==还是equals
  20. 关于spring的applicationContext.xml配置文件的ref和value之自我想法

热门文章

  1. Umount- Linux必学的60个命令
  2. Nginx的几个重要模块
  3. 主从复制系列B
  4. 获取地址栏URL中参数, getQuerySting()方法
  5. netbeans 8.2 系统找不到指定的文件。
  6. com.microsoft.sqlserver.jdbc.SQLServerException: 将截断字符串或二进制数据。
  7. python初学小记
  8. css3之属性选择器
  9. Jdbc封装和对CURD的封装
  10. SSM7-nginx的反向代理和负载均衡