同源策略:
* 同协议: 如都是http或者https
* 同域名: 如https://www.baidu.com/a和https://www.baidu.com/b
* 同端口: 如都是80端口
效果如下:当点击换一组时,从后台获取数据
1. 安装Mock Server
使用Mock Server 模拟请求数据
npm install -g server-mock
命令行中启动服务器
$ mock start
Success: server start success, open the link http://localhost:8080 in browser
2. 配置router.js
app.get('/getNews', function (req, res) {
var news = [
"秦岭鳌太仍有23名驴友失联 两遇难者来自云南",
"观察:谣言转发大户80%是中老年人 精神空虚是主因",
"上海加码楼市调控 新盘销售由公证机构主持摇号",
"28省份取消政府还贷二级公路收费 里程超14万公里",
"北京多条主干道大树被风刮倒 北三环爆堵",
"山东河南蒜苔滞销 万能“大数据”为何也束手无策?"
];
var data = [];
for(var i = 0; i < 3; i ++) {
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
}
res.send(data);
});
3. index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul class="news">
<li>秦岭鳌太仍有23名驴友失联 两遇难者来自云南</li>
<li>观察:谣言转发大户80%是中老年人 精神空虚是主因</li>
<li>上海加码楼市调控 新盘销售由公证机构主持摇号</li>
</ul>
<button class="change">换一组</button>
<script>
var change = document.querySelector('.change');
var newsUl = document.querySelector('.news');
change.addEventListener('click', function () {
var xhr = new XMLHttpRequest();
xhr.open('get', '/getNews', true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState ===4&& xhr.status ===200) {
appendHtml(JSON.parse(xhr.responseText));
}
}
});
function appendHtml(news) {
var html = '';
for (var i = 0; i < news.length; i ++) {
html += '<li>' + news[i] + '</li>';
}
console.log(html);
newsUl.innerHTML = html;
}
</script>
</body>
</html>
3. 使用Hostbuddy
Hostbuddy可以更改域名,以不同的地址访问页面
当浏览器的域名和页面ajax请求路径是同源才能够获取router里的数据。
jsonp 跨域
利用script标签来加载js
router.js
app.get('/getNews', function (req, res) {
var news = [
"秦岭鳌太仍有23名驴友失联 两遇难者来自云南",
"观察:谣言转发大户80%是中老年人 精神空虚是主因",
"上海加码楼市调控 新盘销售由公证机构主持摇号",
"28省份取消政府还贷二级公路收费 里程超14万公里",
"北京多条主干道大树被风刮倒 北三环爆堵",
"山东河南蒜苔滞销 万能“大数据”为何也束手无策?"
];
var data = [];
for(var i=0; i<3; i++) {
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index, 1);
}
var cb = req.query.callback;
if (cb) {
res.send(cb +'(' + JSON.stringify(data)+ ')'); // jsonp
} else {
res.send(data); // get
}
});
index.html
var change = document.querySelector('.change');
var newsUl = document.querySelector('.news');
change.addEventListener('click', function () {
var script = document.createElement('script');
script.src = 'http://a.zj.com:8080/getNews?callback=appendHtml';
document.head.appendChild(script);
document.head.removeChild(script); // 加载后移除,否则每次请求head都会有script标签
});
function appendHtml(news) {
var html = '';
for (var i = 0; i < news.length; i ++) {
html += '<li>' + news[i] + '</li>';
}
console.log(html);
newsUl.innerHTML = html;
}
CORS跨域
CORS全称是跨域资源共享(Cross-Origin Resource Sharing),是一种Ajax跨域请求资源的方式,支持现代浏览器,IE支持10以上,IE8、9部分支持。
实现方式:
当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一些列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-All-Origin;浏览器判断该请求头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以,CORS的表象是让你觉得它与同源的ajax请求无区别。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp</title>
</head>
<body>
<ul class="news">
<li>秦岭鳌太仍有23名驴友失联 两遇难者来自云南</li>
<li>观察:谣言转发大户80%是中老年人 精神空虚是主因</li>
<li>上海加码楼市调控 新盘销售由公证机构主持摇号</li>
</ul>
<button class="change">换一组</button>
<script>
var change = document.querySelector('.change');
var newsUl = document.querySelector('.news');
change.addEventListener('click', function () {
var xhr = new XMLHttpRequest();
xhr.open('get','http://b.zj.com:8080/getNews', true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
appendHtml(JSON.parse(xhr.responseText));
}
};
});
function appendHtml(news) {
var html = '';
for (var i = 0; i < news.length; i ++) {
html += '<li>' + news[i] + '</li>';
}
console.log(html);
newsUl.innerHTML = html;
}
</script>
</body>
</html>
router.js
app.get('/getNews', function (req, res) {
var news = [
"秦岭鳌太仍有23名驴友失联 两遇难者来自云南",
"观察:谣言转发大户80%是中老年人 精神空虚是主因",
"上海加码楼市调控 新盘销售由公证机构主持摇号",
"28省份取消政府还贷二级公路收费 里程超14万公里",
"北京多条主干道大树被风刮倒 北三环爆堵",
"山东河南蒜苔滞销 万能“大数据”为何也束手无策?"
];
var data = [];
for(var i=0; i<3; i++) {
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index, 1);
}
res.header('Access-Control-Allow-Origin', '*');
res.send(data);
});
终端中输入mock start
启动服务
浏览器输入a.zj.com:8080
,而请求数据的地址为b.zj.com:8080/getNews,说明跨域请求成功
控制台中Response请求头中有Access-Control-Allow-Origin:*
,*表示允许任何请求
可以指定为某url:
res.header('Access-Control-Allow-Origin', 'http://a.zj.com:8080');