为什么要使用跨域技术?
在回答和这个问题之前,我们先来理解一下什么是同源策略?
同源策略指的是,不同源地址之间,默认是不能相互发送请求的,这是浏览器的一种安全策略。
那么可能你又会问什么是同源?
所谓的同源就是指完全相同的协议、域名、端口,只有在这种情况下才可以进行AJAX请求。下面列出来的一张表或许你就明白了。
例如与https://blog.csdn.net/index.html
进行对比
http默认协议、及域名(DNS)端口为:80 https为:443
对比地址 | 是否同源 | 原因 |
---|---|---|
http://blog.csdn.net/index.html | 否 | 协议不同 |
https://mp.csdn.net/index.html | 否 | 域名不同 |
https://blog.csdn.net:8080/index.html | 否 | 域名端口不同 |
http://blog.csdn.com/index.html | 否 | 协议与域名不同 |
https://blog.csdn.net/index.html | 是 | 都相同 |
JSONP与CORS的原理:
JSONP原理:
JSONP(json with padding),在客户端借助script
标签向服务端的动态网页(php文件)发起请求,服务端的这个动态网页则返回一段带有函数调用的JavaScript
全局函数的脚本,将原本需要返回给客户端的数据传递过去。
CORS原理:
CORS(跨域资源共享),需要浏览器和服务器同时支持,基本思想为使用自定义的HTTP头部让浏览器和服务器通信。
JSONP的代码实现
JS代码
//封装一个jsonp函数
function jsonp (url, params, callback) {
//防止多次调用函数名重复的问题
var funcName = 'jsonp_' + Date.now() + Math.random().toString().substr(2, 5)
//如果params传入的数据为对象,需要进行转换
if (typeof params === 'object') {
var tempArr = []
for (var key in params) {
var value = params[key]
tempArr.push(key + '=' + value)
}
params = tempArr.join('&')
}
//创建一个script标签
var script = document.createElement('script')
//设置script的请求的地址及回调函数
script.src = url + '?' + params + '&callback=' + funcName
document.body.appendChild(script)
//将函数挂为全局范围
window[funcName] = function (data) {
callback(data)
// 调用完删除 以防全局污染
delete window[funcName]
document.body.removeChild(script)
}
}
jsonp('http://localhost/jsonp/server.php', { id: 123 }, function (res) {
console.log(res)
})
jsonp('http://localhost/jsonp/server.php', { id: 123 }, function (res) {
console.log(res)
})
php代码
<?php
$conn = mysqli_connect('localhost', 'root', '123456', 'demo');
$query = mysqli_query($conn, 'select * from users');
while ($row = mysqli_fetch_assoc($query)) {
$data[] = $row;
}
if (empty($_GET['callback'])) {
header('Content-Type: application/json');
echo json_encode($data);
exit();
}
// 如果客户端采用的是 script 标记对我发送的请求
// 一定要返回一段 JavaScript
header('Content-Type: application/javascript');
$result = json_encode($data);
$callback_name = $_GET['callback'];
echo "typeof {$callback_name} === 'function' && {$callback_name}({$result})";
CORS的代码实现
js代码
$.get('http://localhost/cors.php', {}, function (res) {
console.log(res)
})
php代码
<?php
$conn = mysqli_connect('localhost', 'root', '123456', 'demo');
$query = mysqli_query($conn, 'select * from users');
while ($row = mysqli_fetch_assoc($query)) {
$data[] = $row;
}
// 一行代码搞定
// 允许跨域请求
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($data);