跨域是老生常谈的问题了也是面试会问到的,本质上就是浏览器同源策略javascript
所谓同源策略是浏览器的一种安全策略,所谓同源是指,域名,协议,端口号彻底相同,可是开发者发现浏览器并不会对script标签的src仍是img标签的src,link标签的href限制,因此咱们能够利用这一特性能够进行ajax请求,有同窗可能会问到,我怎么去*证实浏览器对这些标签没有进行同源限制?php
请看下图:html
src或href连接的静态资源,本质上来讲也是一个get请求java
接下来咱们利用这个特性来解决ajax开发中遇到的跨域问题jquery
在jquery开发年代,咱们一般是使用script标签引入对应的js文件,假设咱们如今有a,b两个文件,文件内的代码假设以下:git
a文件:github
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript"> function getData(data){ console.log(data) } </script>
<script type="text/javascript" src="./b.js"></script>
</body>
</html>
复制代码
b文件:面试
getData({name:"vnues"})
复制代码
效果图:ajax
<script type="text/javascript">
// 获得我的信息
let getUserData = function(data){
console.log(data)
};
// 将方法名传给后端
let url = "https://www.vnues.com/user.php?code=123&callback=getUserData"
// 建立script标签,设置其属性
let script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
复制代码
// 数据
$data = [
"name":"vnues",
"age":"18",
"like":"coding"
];
// 接收callback函数名称
$callback = $_GET['callback'];
// 输出
echo $callback . "(" . json_encode($data) . ")";
复制代码
github早已有很是丰富库支持jsonp方法,好比jsonp包,咱们能够经过Promise封装这个jsonpnpm
// npm install jsonp --save
import originJsonp from 'jsonp';
// Promise封装jsonp
export default function jsonp(url, data, option) {
url += (url.indexOf('?') < 0 ? '?' : '') + param(data);
return new Promise((resolve, reject) => {
originJsonp(url, option, (err, data) => {
if (!err) {
resolve(data);
} else {
reject(err);
};
});
});
};
// 将参数拼接到Url中
export function param(data) {
let url = '';
for (let k in data) {
let value = data[k] !== undefined ? data[k] : '';
url += `&${k}=${encodeURIComponent(value)}`;
};
return url.substr(1);
};
复制代码
script标签src连接(地址)不必定是文件也能够是个api接口,只要返回一串调用脚本就能够实现jsonp
实际上jsonp只支持get请求,并不支持post请求,因此这也是开发用的少的缘故