一、cookie封装
function getCookie(key) {
// 获取所有的cookie document.cookie
let cookie = document.cookie;//"username=zhangsan; password=123456"
let arr = cookie.split('; '); //['username=zhangsan','password=123456']
// 遍历arr
for (let i = 0; i < arr.length; i++) { //每一项'username=zhangsan'
// 每一项(arr[i]='username=zhangsan')再次分割
let item = arr[i].split('=');
// item[0]代表键 item[1]代表值
if (item[0] == key) {
return item[1];
}
}
return '';
}
//封装一个设置cookie值得方法
function setCookie(key, value, day) {
let d = new Date();
d.setDate(d.getDate() + day);
document.cookie = key + "=" + value + ";expires=" + d;
}
//删除cookie
function delCookie(key) {
setCookie(key, " ", -1);
}
二、cookie版本购物车(简易版本)
注意点:
1、存储cookie时 ,要求存储的键和值都是字符串类型
2、获取cookie时,获取的值是字符串类型的值
3、将json字符串(jsonstr)转为数组类型,JSON.parse(jsonstr)
4、将数组类型(json)转为json字符串,JSON.stringify(jsonarr)
<table border="1px" id="table">
<thead>
<tr>
<td>商品</td>
<td>单价</td>
<td>数量</td>
<td>小计</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr>
<td>华为手机</td>
<td>7999元</td>
<td> <input type="button" value="-" class="minusnum">
<input type="text" size="2" value="1">
<input type="button" value="+" class="addnum">
</td>
<td class="xj">7999元</td>
<td><input type="button" value="删除" class="delnum"></td>
</tr>
</tbody>
</table>
let table = document.querySelector('table');
let data =
[
{ "product": "华为手机", "price": "7999元", "num": "1", "sumline": "7999元" },
{ "product": "小米手机", "price": "9888元", "num": "1", "sumline": "9888元" },
{ "product": "诺基亚手机", "price": "8999元", "num": "1", "sumline": "8999元" },
{ "product": "锤子手机", "price": "9999元", "num": "1", "sumline": "9999元" }
]
function render() {
let str = ''
let cookie = JSON.parse(getCookie('data'));//
cookie.forEach((item, index) => {
str += ` <tr>
<td>${item.product}</td>
<td>${item.price}</td>
<td> <input type="button" value="-" class="minusnum">
<input type="text" size="2" value="${item.num}">
<input type="button" value="+" class="addnum">
</td>
<td class="xj">${item.price}</td>
<td><input type="button" value="删除" index = ${index} class="delnum"></td>
</tr>`
})
this.table.children[1].innerHTML = str;
}
render();
table.onclick = function (e) {
let ev = e || window.event;
if (ev.target.className == 'delnum') {
let index = e.target.getAttribute('index');
// 获取cookie
let cookie = JSON.parse(getCookie('data'));
// 操作cookie
cookie.splice(index,1)
// 设置cookie
setCookie('data',JSON.stringify(cookie),7)
// 刷新
render();
}
}
三、同源策略
3.0 什么叫同源
如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)http://www.example.com:81/dir/other.html:不同源(端口不同)
https://www.example.com/dir/page.html:不同源(协议不同)
3.1 什么叫同源策略
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问
3.2 同源策略的目的
为了安全,如果没有同源限制,在浏览器中的cookie等其他数据可以任意读取,不同域下的进行可以任意操作,ajax任意请求其他网站的数据,包括隐私数据。
3.3 非同源受到的限制
- cookie不能读取 (如我在自己的站点无法读取博客园用户的cookie)
- dom无法获得。
- ajax请求不能发送
四、跨域
4.1 什么叫跨域
通俗的讲,跨域访问,就是跨域名访问,即A网站的网页的代码可以访问了B网站的页面。
4.2 jsonp跨域原理
jsonp 是 json with padding 的缩写,它不属于 Ajax 请求,但它可以模拟 Ajax 请求
页面上的很多标签天生就有跨域能力,都不会受到同源策略的影响比如:img,link,iframe,script。
jsonp就是利用<script>的src来实现跨域获取数据的,只支持get请求。
jsonp 由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数。
- 回调函数的名字一般是在请求中指定的。
- 而数据就是传入回调函数中的 JSON 数据
4.3 jsonp跨域的实现步骤
- 将不同源的服务器端请求地址写在 script 标签的 src 属性中
<script src="www.example.com?callback=fn&username=zhangsan"></script>
2.在客户端全局作用域
function fn(data){}
- 在fn函数内部对服务器端返回的数据进行处理
function fn(data){
console.log(data);
}
服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
const data = 'fn({name: "张三", age: "20"})';
echo data;
整体实现思路:
- 客户端需要将函数名称传递到服务器端
- 将script请求的发送变成动态的请求。
- 服务器端在后端返回一个函数调用
- 客户端接收到响应,直接调用全局函数
前端
<script>
function fn(data){
console.log(data);
}
// 接收后端响应的数据
</script>
<script src="data.php?callback=fn"></script>
后端:
<?php
$cb = $_GET['callback']; //接收前端的参数:callback fn
$data = "i am back";
echo $cb.'("'.$data.'")'; // fn('123')
?>
4.4 jsonp跨域封装(直接拿来使用即可)
function $jsonp(options) {
var oScrc = document.createElement('script');
// window[fn]:将fn函数挂载在全局作用域下
// 将传入的函数 转为window对象下
var fn = 'myfn'+Math.random().toString().replace('.','');
// fn随机函数名
window[fn] = options.success;
oScrc.src = options.url + '?cb=' + fn+'&' + getParams(options.data);
document.body.appendChild(oScrc);
oScrc.onload = function () {
this.remove();
}
}
// 将js对象{}转为字符串拼接的形式 username=zhangsa&password=12345
function getParams(obj){
var arr = [];
for(var k in obj){
arr.push(k+'='+obj[k]);
}
return arr.join('&');
}
调用的的格式:
$jsonp({
url:'https://www.baidu.com/sugrec',
data:{
"prod":"pc",
"wd":"衣服",
},
success:function(data){
console.log(data);
}
})
五、跨域访问的几种方式
5.1 服务器端跨域(CORS跨域)
CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制。
只需要在后端设置:
header('Access-Control-Allow-Origin: *');//允许任何请求
header('Access-Control-Allow-Origin: 'http://localhost:3000'');允许localhost:3000发起的跨域请求,其他的都不通过
5.2 jsonp跨域
5.3 后端代理解决跨域
六、JSONP实现百度搜索
简述:后期做开发,我们不需要写php后端代码,。学会看后端的接口文档就可以啦
下面就是一个写好的接口文档。
后端接口:
url:'https://www.baidu.com/sugrec'
请求参数:
prod:什么端访问的pc,android
wd: 搜索内容
例如:
"prod":"pc"
"wd":"衣服"