JSONP
一、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>`
})
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();
}
}
二、HTTP协议
程序员必备基础知识:通信协议–Http,TCP,UDP
1.1通信协议
都是通信协议,也就是通信时所遵守的规则,只是双方都按照这个规则 “ 说话”,对方才谈理解
计算机只所以能全世界互通,协议是功不可没。如果没有协议,计算机各说各话,根本谁都听不懂谁。
1.2计算机常见的网络协议
常见的网络协议:HTTP、TCP、UDP、FTP
其中最常见的就是TCP和UDP
TCP和UDP都工作在传输层,他们的目标都是在程序之间传输数据的。他们传输的数据格式可能是图片,视频,文本文件
TCP和UDP的区别?
TCP是基于连接的一种协议,UDP基于非连接
TCP是如何保证以上过程的呢?
-
三次握手:建立连接的过程
○ 也就是客户端向服务器端发起连接时,会先发一包连接请求数据进行询问,是否可以和服务器建立连接
○ 如果服务器端同意客户端的请求,就会发送一包数据表示确认连接
○ 客户端收到服务器端的确认之后,再次发送一包数据,表示 双方可以进行数据传输啦 -
传输确认
-
四次挥手
○ 客户端主动发起关闭请求,向服务器端发送一包数据,表示要关闭连接
○ 服务器端收到这包数据,又发送一个确认的包给客户端
○ 服务器端再次发送一个确认包给客户端
○ 客户端收到服务端的数据包,最后发送给服务器端一个确认包
即我们通常所说的Request/Response. 前端向后端发送请求
需要建立连接(三次握手),如果数据传输完成,就需要断开连接(四次挥手)
1.和服务器建立连接(三次握手)
2.建立连接后,发送一个请求给服务器(请求)
3.服务器该受到请求以后进行相应的处理并给出一个回应(响应)
4.断开与服务器的连接
数据传输
先连接(三次握手)–> 数据传输 --> 断开连接(四次挥手)–> 数据停止传输
1.3什么是Http协议
Http是基于TCP的图向连接的一种协议。HTTP协议是一种基于请求/响应模式的、无状态的协议
HTTP协议的主要特点可概括如下:
1、支持客户/服务器模式。
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。
3、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
4、无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5、无状态:HTTP协议是无状态协议。无状态协议是指协议对于事务处理没有记忆功能。
1.4 HTTP协议之URL
1.5HTTP协议之请求
http请求有三部分组成,分别是:请求行,消息报头,请求正为。
输入地址栏回车,对 URL 进行解析之后,浏览器确定了目标服务器和文件名,接下来就需要根据这些消息封装成一个 HTTP 请求报文发送出去
请求报文 和 响应报文 都是由三个部分组成
- 前台应用从浏览器端, 向后台服务器发送HTTP请求(请求报文)
- 后台服务器端接收到请求后, 调用服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
- 浏览器端接受到响应, 解析显示响应体
1.6 HTTP协议之响应
常见的请求方式:
get请求,将请求数据作为url一部分发送,不安全,传输数据量小,方便易用。
post请求,传输数据量大,安全,一般做表单提交。
常见响应状态码:
200 OK //客户端请求成功
400 Bad Request // 客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
三、同源策略
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 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
总结
同源策略∶Ajax请求地址与当前页面的地址必须得是同协议,同主机,同端口才可以正常发送Ajax请求,这三者有任何一个不一样,则判定此次请求是跨域请求,浏览器会泪止这个请求行为。
3.2同源策略的目的
为了安全,如果没有同源限制,在浏览器中的cookie等其他数据可以任意读取,不同域下的进行可以任意操作,ajax任意请求其他网站的数据,包括隐私数据。
3.3非同源受到的限制
● cookie不能读取 (如我在自己的站点无法读取博客园用户的cookie)
● dom无法获得。
● ajax请求不能发送
四、跨域
4.0什么叫跨域
通俗的讲,跨域访问,就是跨域名访问,即A网站的网页的代码可以访问了B网站的页面。
4.1 jsonp跨域原理
jsonp是 json with padding 的缩写,它不属于 Ajax 请求,但它可以模拟 Ajax 请求
页面上的很多标签天生就有跨域能力,都不会受到同源策略的影响比如:img,link,iframe,script。
jsonp就是利用 < script > 的src来实现跨域获取数据的,只支持get请求。
jsonp 由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数。
● 回调函数的名字一般是在请求中指定的。
● 而数据就是传入回调函数中的 JSON 数据
4.2 jsonp跨域的实现步骤
1.将不同源的服务器端请求地址写在 script 标签的 src 属性中
<script src="www.example.com?callback=fn&username=zhangsan"></script>
2.在客户端全局作用域
function fn(data){}
3.在fn函数内部对服务器端返回的数据进行处理
function fn(data){
console.log(data);
}
4.服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
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')
?>
jsonp解决跨域的用途是非常广的,很多网站进去都能看到很多的jsonp跨域
4.3 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);
}
})
五、跨域访问的几种方式
服务器端跨域(CORS跨域)
CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制。
只需要在后端设置:
header('Access-Control-Allow-Origin: *');//允许任何请求
header('Access-Control-Allow-Origin: 'http://localhost:3000'');允许localhost:3000发起的跨域请求,其他的都不通过
六、JSONP实现百度搜索
简述:后期做开发,我们不需要写php后端代码,。学会看后端的接口文档就可以啦
下面就是一个写好的接口文档。
后端接口:
url:'https://www.baidu.com/sugrec'
请求参数:
prod:什么端访问的pc,android
wd: 搜索内容
例如:
"prod":"pc"
"wd":"衣服"
七、请求天气预报
接口文档:
请求方式:GET
请求地址: 'https://wis.qq.com/weather/common',
必要参数:
province: "陕西省",
city: "西安市",
source:'pc',
weather_type:'forecast_1h'
搜索框自动搜索
<!DOCTYPE html>
<html>
<head>
<title>千锋教育——做真实的自己,用心做教育</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<input type="text">
<script src="./jsonp.js"></script>
<script>
var oTxt = document.querySelector('input')
oTxt.oninput = function () {
jsonp({
type:'GET',
url: 'https://suggest.taobao.com/sug',
data: {
q: this.value,
},
success: function (data) {
console.log(data);
}
})
}
</script>
</body>
</html>