jsonp到底是什么?
在面试的时候问跨域怎么解决,通常第一个回答就是jsonp,虽然工作中不常用,但是没有弄懂总是会觉得心里没底。今天就利用nodejs来从前端到后端完全弄明白,什么是jsonp。
Web页面上调用js文件时则不受是否跨域的影响,其实,凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>。
所以就有人利用这个特性实现跨域传递数据。我们可以调用跨域服务器上动态生成的js格式文件,也就是调用JSON文件,获取自己需要的数据。
后来逐渐形成了一种非正式的传输协议,也就是JSONP。该协议允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,客户端接收到响应后执行回调并且可以对数据进行各种需要的处理。
jsonp跨域原理:
动态创建script标签,利用script标签的src属性没有跨域限制,我们在前端提前定义好一个函数名(约定俗成为callback),后端返回的是一个callback() 形式的代码片段,
前端定义一个函数名相同的函数,此时可以拿到这个函数的参数,就是要获取的数据。
jsonp的优点:
JSONP可以跨越同源策略,实现跨域传输
JSONP兼容性更好,在更加古老的浏览器中都可以运行
在请求完毕后可以通过调用callback的方式回传结果。将回调方法的权限给了调用方
jsonp的缺点:
只支持get请求。
安全性不高。如果提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的,那么所有调用这个jsonp的网站都会存在漏洞
实现:
前端:
<script>
let oScript = document.createElement('script')
oScript.src = 'http://localhost:3000/api/getValue?callback=getValue'
document.body.appendChild(oScript)
function getValue(data){
console.log(data) //{name: 'zhangsan', age: 18}
}
</script>
后端:
let http = require('http')
let url = require('url')
http.createServer((req,res)=>{
let data = url.parse(req.url,true)
console.log(data)
let callback = data.query.callback
if(data.pathname === '/api/getValue'){
res.end(`${callback}(${JSON.stringify({
name:'zhangsan',
age:18
})})`)
}else{
res.end("404")
}
}).listen(3000,()=>{
console.log('server run ...')
})