学习目标:
- 了解什么是跨域
- 理解产生跨域的原因
- 用哪些方法可以解决跨域
- 模板引擎doT.js
学习内容:
1、 了解什么是跨域
2、 理解产生跨域的原因
3、 解决跨域的方法
4、 模板引擎doT.js
学习时间:
1、 周一至周六早上 8 点—晚上9点
一、什么是跨域?
跨域,指的是浏览器不能执行其他网站的脚本
简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象
例子:比如淘宝网不能请求京东的数据
产生跨域的原因
由浏览器的同源策略造成的
同源策略,它是由Netscape提出的一个著名的安全策略。
现在所有支持JavaScript 的浏览器都会使用这个策略。
举个例子 通俗讲:
生活中,社会能够安定的运行,有一个前提,大家都默认遵守一个协定:每个人只能自由的出入自己的家,拿取自己家的东西。而如果大家都不遵循这种协定,你可以随便去拿别人家的东西,别人也可以随便的出入你的家,这样社会就乱套了。此处大家都遵循的各用各家的东西,就叫做同源策略
二、跨域的限制及解决方法
1.限制
随着互联网的发展,同源政策越来越严格。目前,如果非同源,共有三种行为受到限制。
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。【缓存数据】
- 无法接触非同源网页的 DOM。
- 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)
查看LocalStorage:
右键 ,检查,application,localStroage
2.方法
1、设置CORS跨域资源共享
后台在请求头信息里面添加:服务端:、
response.setHeader("Access-Control-Allow-Origin", "*");
“*”表示所有的域都可以接受
CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能。
2、Ajax 跨域请求
由于在工作中需要使用AJAX请求其他域名下的资源,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地,同域的资源,而不能跨域访问
可以让服务器去别的网站获取内容然后返回页面
通俗的讲就是:
租房子,房源被中介给垄断了,我们无法直接找到房东。
需要先找到中介,中介去和房东谈具体事宜,谈好以后把每个月多少钱的信息告诉我们
3、Jsonp
比如:
通过img的src属性,访问百度的图片:
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1910846161,216642357&fm=26&gp=0.jpg" alt="">
jsonp就是利用script标签的跨域能力请求资源
Jsonp 实现思路:
- 全称是 JSON with Padding,请求时通过动态创建一个 Script,在 Script 中发出请求,
- 通过这种变通的方式让请求资源可以跨域。
- 它不是一个官方协议,是一个约定,约定请求的参数里面如果包含指定的参数(默认是 callback),就说明是一个 JSONP 请求,服务器发现是 JSONP 请求,就会把原来的返回对象变成 JS 代码。
- JS 代码是函数调用的形式,它的函数名是 callback 的值,它的函数的参数就是原来需要返回的结果。
- 后台会把函数调用,重新返回给前端
jsonp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp</title>
</head>
<body>
<script>
// 调用后台函数
function turn(value){
console.log(value);
}
</script>
<!--
通过script的src属性进行跨域
传递的参数默认是callback
后台看到callback就能够判断出来是一个jsonp请求
会根据callback的值,自动生成函数,函数名就是callback的值
后台把数据封装成对象,作为参数传递给函数作为值
-->
<script src="./test.js?callback=turn"></script>
</body>
</html>
test.js
// test.js就是我们模拟的后台
// 后台能判断出来是否是jsonp请求
// 如果是,就会生成一个函数的调用,而函数名,就是前端提交上来的callback的值在假如我们要给前端返回一个数据
var data = {
"name":"张三",
age : 20,
address:"美国"
}
// 在后台生成了函数的调用,把数据以参数的形式,进行传递
// 后台会把这个函数的调用,重新返回给前端
turn(data);
使用node.js模拟jsonp
/*
jsonp 接口地址:
http: //localhost:3003/jsonp?callback=test
传参数
约定请求的参数中的指定参数:callback
服务器发现是 JSONP 请求, 就会把原来的返回对象变成 JS 代码。
JS 代码是函数调用的形式, 它的函数名是 callback 的值,
它的函数的参数就是原来需要返回的结果。
*/
//通过require将http库包含到程序中
let http = require('http');
//引入url模块解析url字符串
let url = require('url');
//引入querystring模块处理query字符串
let querystring = require('querystring');
//创建新的HTTP服务器
let server = http.createServer();
//通过request事件来响应request请求
server.on('request', function (req, res) {
let urlPath = url.parse(req.url).pathname;
let qs = querystring.parse(req.url.split('?')[1]);
// 如果请求路径里面包含有jsonp 和callback 就判断出来这是一个jsonp请求
if (urlPath === '/jsonp' && qs.callback) {
res.writeHead(200, {
'Content-Type': 'application/json;charset=utf-8'
});
// 此处的data数据 就是后台要返回个前端的数据
let data = {
"msg": "jsonp返回的数据",
"fn": qs.callback
};
data = JSON.stringify(data);
// 根据callback的值,创建函数 data 是函数内传递的参数
let callback = qs.callback + '(' + data + ');';
console.log(callback);
// 向前端进行响应
res.end(callback);
} else {
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf-8'
});
res.end('Hell World\n');
}
});
server.listen(3003,'localhost',function(){
console.log('your server is running here:localhost:3003');
});
2、使用node命令启动文件
3、创建html文件,jsonp_server.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function test(v){
console.log(v);
}
</script>
<!-- callback:是后台定好的,如果规定是其他的,例如backcall / cb你在传参数是,就要按规定来,传bcakcall /cb
test:具体的参数的值,可以根据后台的规定来定义
例如:后台规定参数的值,必须叫test那你就只能写testI -->
<script src="http://localhost:3003/jsonp?callback=test"></script>
</body>
</html>
JSONP优缺点:
优点:兼容性强&不受同源策略的限制
缺点:只能用get方法,不能使用post方法
因为get请求方式把请求参数放在了url地址中,后台解析jsonp是通过url的callback参数进行判断的,所以之支持get请求
4、WebSocket 【了解】
WebSocket 是一种通信协议,和http,https是同一级别的。
使用ws://(非加密)和wss://(加密)作为协议前缀。
该协议不实行同源政策,只要服务器和浏览器支持,就可以通过它进行跨源通信。
缺点
只有在支持websocket协议的服务器和浏览器上才能正常工作
websocket不支持ie6以下的浏览器
webSocket在线测试网站:
http://www.websocket-test.com/
doT.js 模板引擎
1、找到提供好的doT.json 文件,作为数据放进项目中
2、创建展示数据的html文件
通过ajax获取json数据,
在页面中动态的通过点击把数据展示在页面中
show_data.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
li{
list-style: none;
}
div{
border-bottom: 3px solid #999;
padding-bottom: 10px;
width: 400px;
}
img{
width: 390px;
}
</style>
</head>
<body>
<button onclick="show()">展示数据</button>
<ul id="list">
</ul>
<script>
function show(){
var ajax_ = new XMLHttpRequest || new ActiveXObject('Microsoft.XMLHTTP');
ajax_.open('get','./doT.json',true);
ajax_.send();
ajax_.onreadystatechange = function(){
if(ajax_.readyState == 4){
if(ajax_.status== 200){
var res = JSON.parse(ajax_.responseText);
console.log(res);
//把数据渲染到页面上
render_html(res);
}
}
}
function render_html(v){
var str = '';
for(var i=0;i<v.list.length;i++){
str+= '<li>';
str+='<p>'+v.list[i].imgtitle+'</p>'
str+='<img src="'+v.list[i].imgurl+'" alt="">'
str+='<div>'+v.list[i].note+'</div>'
str+= '</li>';
var list_ = document.getElementById('list');
list_.innerHTML = str;
}
}
}
</script>
</body>
</html>
复制showData.html,使用doT模板引擎来实现
1、在html页面中复制引入doT.js
2、找到数据源
即使用ajax接收到的数据
<script>
function show() {
var ajax_ = new XMLHttpRequest || new ActiveXObject('Microsoft.XMLHTTP');
ajax_.open('get', './doT.json', true);
ajax_.send();
ajax_.onreadystatechange = function () {
if (ajax_.readyState == 4) {
if (ajax_.status == 200) {
/* 2、得到数据源 */
var res = JSON.parse(ajax_.responseText);
console.log(res);
/* 5.调用方式 */
// var tmpText = doT.template(模板);
// tmpText(数据源);
var tmpText = doT.template(document.getElementById('li_tmpl').innerText);
document.getElementById('list').innerHTML = tmpText(res.list);
}
}
}
}
</script>
3、找到展示区域
<button onclick="show()">展示数据</button>
<!-- 3、展示区域 -->
<ul id="list">
</ul>
ul就是我们的展示区域
4、准备模板
<!-- 4、准备模板 模板id是自定义的 -->
<script id="li_tmpl" type="text/x-dot-template">
</script>
5、调用方式:
ajax_.onreadystatechange = function () {
if (ajax_.readyState == 4) {
if (ajax_.status == 200) {
/* 2、得到数据源 */
var res = JSON.parse(ajax_.responseText);
console.log(res);
/* 5.调用方式 */
// var tmpText = doT.template(模板);
// tmpText(数据源);
var tmpText = doT.template(document.getElementById('li_tmpl').innerText);
document.getElementById('list').innerHTML = tmpText(res.list);
}
}
}
6、展示数据
<!-- 4、准备模板 模板id是自定义的 -->
<script id="li_tmpl" type="text/x-dot-template">
<!-- 6、展示数据 -->
{{~it:value:index}}
<li>
<p>{{= value.imgtitle}}</p>
<img src="{{= value.imgurl}}" alt="">
<div>{{= value.note}}</div>
</li>
{{~}}
</script>
总结
以上就是今天的内容,本文介绍了什么是跨域,跨域产生的原因,可以用哪些方法解决跨域,以及模板引擎doT.js。
重点:模板引擎doT.js