一、jsonp跨域是什么
1、由来
在Web应用中,为了保证用户浏览的速度,许多网页会采用Ajax技术在页面上进行部分刷新,在这个过程中,为了保护用户的信息和系统的安全,服务器放置了许多控制访问的机制,如同源策略(Same Origin Policy)。这个策略禁止一个网页去调用另一个来源的页面上的资源。例如,stogege.com的网页脚本无法取得www.google.com的内容,因为它们不是同源。
但有些情况下,我们需要在不同的域名或端口之间进行数据交互,这时候就需要使用jsonp跨域技术。
2、原理
JSONP(“JSON with padding”)是JSON的一种“使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。Jsonp的实现方法就是在服务器端加上一个回调函数,然后返回时将数据作为这个回调函数的参数,然后客户端通过 script 标签引入这个 URL,就可以拿到远程返回的 JS 代码,并在回调函数里面拿到拿到数据了。由于同源策略的限制,XmlHttpRequest无法跨越域名获取数据,而script标签的SRC属性是没有跨域限制的。这样适用JSONP实现跨域数据请求。
// client端 function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } window.onload = function () { addScriptTag('http://domain2.com:8080/login?user=admin&callback=foo'); }; function foo(data) { alert('Your name is ' + data.name); } // server端 if (url.parse(req.url, true).pathname === '/login') { var data = {name: 'admin'}; var callback = url.parse(req.url, true).query.callback; if (callback) { res.end(callback + '(' + JSON.stringify(data) + ')'); } else { res.end(JSON.stringify(data)); } }
二、jsonp的优缺点
1、优点
(1)兼容性好:JSONP在实现上比较简单,在老式浏览器上都可以兼容正常使用;
(2)能够使用不同源下的已存在的服务:JSONP通过script标签来调用,无须Ajax的标准化支持,因此可以跨越不同源而无需要后台支持;
2、缺点
(1)可读性差:JSONP返回的数据要求是JSON格式的,这种格式对于阅读来说不太友好,可读性差;
(2)不安全:JSONP是可以进行跨域操作的,也就意味着当被请求的服务存在安全漏洞时,这种操作可能会导致一定的安全风险,代码难以维护。
三、jsonp的应用场景
1、富客户端Web应用
富客户端Web应用通常需要动态获取各种数据,这些数据通常来自不同的域名,而JSONP正是一种跨域的手段,使得这些数据能够被成功地获取。
2、第三方数据解析
第三方的数据解析通常有两种方式:一个是通过后台进行转发,另外一个就是使用JSONP来实现,将解析到的数据直接返回到前端,使用JSONP进行数据解析。
四、jsonp的实现过程
1、前端请求
function jsonp(url, params, callback) { const script = document.createElement('script'); const src = url + '?' + jsonpParams(params, callback); script.setAttribute('src', src); document.body.appendChild(script) } function jsonpParams(params, callback) { let str = ''; const callbackName = 'jsonp_callback_' + parseInt(+new Date() / 1000); window[callbackName] = (data) => { try { callback && callback(data); } catch (e) {} delete window[callbackName]; document.body.removeChild(script); }; str = 'callback=' + callbackName; for (let key in params) { str += '&' + key + '=' + params[key]; } return str; } jsonp('http:// domain2.com:8080/login', {user: 'admin'}, (data) => { console.log(data); });
2、后端响应
if (/^\/api\/jsonp$/i.test(req.pathname)) { const data = JSON.stringify({id: 1, name: 'test'}); res.end(`${req.query.callback}(${data})`); }
五、jsonp的安全问题
使用JSONP跨域时,由于callback参数不是用户手动输入的,而是后台修改后返回给前端的,所以不会被攻击者通过输入脚本的方式进行攻击。但是如果不对服务端返回的数据进行过滤的话,就会存在XSS攻击的风险。使用JSONP跨域时,服务端应该仅返回经过校验的、安全的数据。
六、总结
jsonp跨域技术是在Web应用的开发中经常使用的一种技术手段。虽然它有许多限制和不足,但因其简单易懂,兼容性好,能够优雅地解决同源策略问题,而被广泛应用于Web应用的开发中。