全称 JSON with Padding,用于解决AJAX跨域问题的一种方案。
由于同源策略的限制,浏览器只允许XmlHttpRequest请求当前源(域名、协议、端口)的资源,而对请求script资源没有限制。通过请求script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,这种跨域的数据的方式被称为JSONP。
实现原理
1.首先在客户端注册一个callback方法,放到window对象上,如:
callbackFunction (json) { console.log(JSON) }
然后把callback的名字(callbackFunction)传给服务器。
2.服务器先生成 JOSN 数据。
3.将 JOSN 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档(如callbackFunction(JOSN)),返回给客户端。
4.客户端浏览器,将返回的JS标签插入DOM,解析script标签后,会执行callbackFunction(JOSN)。
通过这种方式,即可实现跨域获取数据。
Code
import { JSONP } from './JSONP' // 调用 JSONP({ url: 'url', data: { key1: 'key1' }, callback (data) { // data 是服务端返回的数据 } })
// JSONP.js let JSONP = (config = {}) => { let { data, url, callback } = config // 拼接请求Url if (!url) throw new Error('url is required!') let name = `id_${(new Date()).getTime()}_${Math.random().toString().substr(2)}` let srcUrl = getSrcUrl(url, { data, callback: name }) // 插入Script标签 let script = document.createElement('script') script.type = 'text/javascript' script.src = srcUrl script.id = name // CallBack 放到 window 对象,调用后销毁 window[name] = function(json){ // 执行这个函数后,要销毁这个函数 window[name] = undefined // 获取这个script的元素 var elem = document.getElementById(name) // 删除head里面插入的script,这三步都是为了不影响污染整个DOM啊 removeElem(elem) // 执行传入的的函数 callback && typeof callback === 'function' && callback(json) } var head = document.getElementsByTagName('head') if (head && head[0]) { head[0].appendChild(script) } } let getSrcUrl = (url, data) => { let _url = url + (url.indexOf('?') === -1 ? '?' : '&') let ret = '' if (typeof data === 'string') { ret = data } else if (typeof data === 'object') { for (let key in data) { ret += '&' + key + '=' + encodeURIComponent(data[key]) } } ret = ret.substr(1) return _url + ret } let removeElem = (elem) => { let parent = elem.parentNode if (parent && parent.nodeType !== 11) { parent.removeChild(elem) } } export default JSONP
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。