jsonp介绍
为了保证用户信息的安全,防止恶意的网站窃取数据,目前所有浏览器都实行了同源策略,而不同源 则跨域。
同源策略
最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。现在浏览器的所谓"同源"指的是"三个相同":
- 协议相同
- 域名相同
- 端口相同
例如:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制:
- Cookie、LocalStorage 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域。而jsonp就是解决同源策略限制的一种方法。
JSONPJSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。
原理:
服务端返回一个预先定义好的javascript函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。
!--不受同源策略的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>
例:
为了演示我开启了一个端口号为9999的服务器,
后端代码:
const http = require'http')
const url = require'url')let server = http.createServer)
server.on'request', req, res) => {
//解构出路径,路径重命名为URL和查询字符串let { pathname: URL, query } = url.parsereq.url, true)console.logurl.parsereq.url, true));console.log'URL---', URL);console.log'query---', query);if URL == '/index') {let obj = { name: '张三', age: 22 }// 响应数据,返回json字符串(getName"{ "name": "张三", "age": 22 }"))给前端res.end`${query.callback}${JSON.stringifyobj)})`)} else {res.end'404')}
})
server.listen9999, ) => {console.log'server is runing...');})
前端代码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><button id="submit">jsonp请求</button><script>// 将来后端返回的数据用形参data接收function getNamedata) {console.logdata);}document.querySelector'#submit').onclick = function ) {console.log'ok');// 尝试1:失败,无法访问,因为跨域了// var xhr = new XMLHttpRequest)// xhr.open'get', 'http://localhost:9999/index')// xhr.send)// xhr.onload = function ) {// console.logxhr.responseText);// }// 尝试2:jsonp原理实现跨域,成功var newscript = document.createElement'script')newscript.setAttribute'src', 'http://localhost:9999/index?callback=getName')document.body.appendChildnewscript)}</script><!-- <script src="http://localhost:9999/index?callback=getName"></script> -->
</body></html>
简单来讲就是前端抛出一个函数名给后端,后端将前端需要的数据作为实参并返回该函数给前端,该函数真正调用在前端。有点像钓鱼的过程。
jquery对于jsonp的封装
只需要将dataType写成jsonp即可,其他还是照常写
例:
//使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
$.ajax{type:"get",url:"http://www.api.com/testjs.php",dataType:"jsonp",data:{uname:"hucc",upass:"123456"},success:function info) {console.loginfo);}
});