跨域
概念
同源策略是浏览器的一种安全策略,所谓同源是指 域名,协议,端口完全相同,只要同源的地址才可以相互通过AJAX的方式请求
同源或者不同源的是两个地址之间的关系,不同源地址之间请求我们称之为跨域
同源策略
指的是:不同源地址之间,必须服务端和客户端配合才能完成
尝试找到一种可以发送不同源请求的方式
<script>
//请求一个不同源的地址实际上就是我们所说的跨域请求
//## 1. img
//可以发送不同源地址之间的请求,但是无法拿到响应结果
// var img =new Image();
// img.src='http://locally.uieee.com/categories';
//## 2. link
//可以发送不同源地址之间的请求,但是无法拿到响应结果
// var link = document.createElement('link');
// link.rel = 'stylesheet';
// link.href = 'http://locally.uieee.com/categories';
// document.body.appendChild(link);
// ## 3. script
var script = document.createElement('script');
script.src = 'http://localhost/time2.php';
document.body.appendChild(script);
</script>
JSONP
JSON with Padding
是一种借助于script标签发送跨域请求的技巧
其原理就是在客户端借助script标签请求服务端的一个动态网页(php文件),服务端的这个动态网页返回一段带有函数调用的JavaScript全局函数调用的脚本,将原本需要返回给客户端的数据传递进去
以后绝大多数情况都是采用JSONP的手段完成不同源地址之间的跨域请求
总结:
由于XMLHttpRequest无法发送不同源地址之间的跨域请求,所以我们必须另寻他法,script这种方案就是我们最终选择的方式,这个方式成为JSONP,
问题:
1.JSONP需要服务端配合,服务端按照客户端要求防返回一段JavaScript调用客户端的函数
2.只能发生GET请求
注意:
JSONP用的是script标签,跟AJAX提供的XMLHttpRequest没有任何关系
通过script标签请求一个服务器的PHP文件,这个文件返回的结果是一段JS,
作用是调用我们事先定义好的一个函数,
从而将服务器想要给客户端发过去的数据发送给客户端-
jQuery中ajax的封装
$.ajax({
url: 'json.php',
type: 'get',
data: {id: 1, name: '张数'},
// 用于设置响应体的类型,注意:跟data参数没有关系
dataType: 'json',
success: function (res) {
//res 会自动根据服务器响应的Content-Type自动转换为对象,这是jQuery内部实现的
// 一旦设置的dataType选项,就不再关心服务端响应的 Content-Type
// 客户端会主观认为服务端返回的就是JSON格式的字符串
console.log(res);
}, error: function (xhr) {
//只有请求不正常才会执行(状态码不为200)
console.log(xhr);
},complete: function (xhr) {
// 请求完成, 成功/失败 都会执行
}
});
JQuery全局事件处理
$(document).ajaxStart(function () {
// 只要有ajax请求发生,就会执行
$(".loading").fadeIn();
console.log("请求开始了")
}).ajaxStop(function () {
// 只要有ajax请求结束,就会执行
$(".loading").fadeOut();
console.log("请求结束了")
});
jQuery高度封装的函数
$.get('time.php', {id: 1}, function (res) {
console.log(res);
});
$.pose('time.php', {id: 5}, function (res) {
console.log(res);
});
回调
function getTimeStamp(done) {
setTimeout(function () {
// 执行指定的事情
done(Date.now());
})
}
var done = function (timeStamp) {
console.log(timeStamp / 1000 / 60 / 60);
};
getTimeStamp(done);
CORS
Cross Origin Resource Share
跨域资源共享
header('Access-Control-Allow-Origin:*');
这种方案无需客户端做出任何修改,只要在被请求的服务端响应的时候添加一个Access-Control-Allow-Origin响应头,表示这个资源十分允许指定域请求。
jsonp 封装
function jsonp(url, params, callback) {
var funcName = 'jsoup_' + Date.now() + Math.random().toString().substring(2, 5);
if (typeof params === 'object') {
var tempArr = [];
for (var key in params) {
var value = params[key];
tempArr.push(key + "=" + value);
}
params = tempArr.join('&');
}
var script = document.createElement('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);
})
案例:loading
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页面</title>
<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="../nprogress.css">
<style>
.loading {
display: none;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, .6);
font-size: 30px;
}
</style>
<script src="../nprogress.js"></script>
</head>
<body>
<div class="container pt-4">
<h1>会员中心</h1>
<hr>
<div class="row">
<aside class="col-md-3">
<div class="list-group">
<a class="list-group-item list-group-item-action" href="index.html">我的资料</a>
<a class="list-group-item list-group-item-action" href="cart.html">我的购物车</a>
<a class="list-group-item list-group-item-action" href="orders.html">我的订单</a>
</div>
</aside>
<main id="main" class="col-md-9">
<h2>我的个人资料</h2>
<hr>
</main>
</div>
</div>
<div class="loading">正在玩命加载中...</div>
<script src="../jquery.js"></script>
<script>
$(function ($) {
$(document)
.ajaxStart(function () {
NProgress.start()
})
.ajaxStop(function () {
NProgress.done()
});
// 有一个独立的作用域,顺便确保页面加载完成执行
$('.list-group-item').on('click', function () {
var url = $(this).attr('href');
$('#main').load(url + ' #main > *');
return false
})
})
</script>
</body>
</html>
网友评论