网络全部笔记
# 向浏览器的地址栏中输入一个url按回车之后,网络中都会发生什么?
答:
1.看浏览器的缓存
2.看本机的host
C:/windows/system32/drivers/etc/host
127.0.0.1 localhost
3.家里路由器,上级路由,城市的LDNS服务器,继续向上级的DNS服务器找,直到找到GDNS服务器
# HTTP协议简介
- HTTP协议分为两个部分
1.请求 Request
请求头:
请求方式:GET、POST...
路径:url
协议版本:HTTP/1.1
数据体
2.响应 Response
- GET请求和POST请求的区别
1.是基于什么前提的?若什么前提都没有,不使用任何规范,只考虑语法和理论上的HTTP协议
GET和POST几乎没有任何区别,只有名字不一样
2.若是基于RFC规范的
1).理论上(Specification):GET和POST具有相同的语法,但是有不同的语义。GET是用来获取数据的,POST是用来发送数据的,其他方面没有区别。
2).实现上的(Implementation):各种浏览器,就是这个规范的实现者。
常见的不同:
a.GET的数据在URL是可见的。POST的请求不显示在URL中
b.GET请求对长度是有限制的。POST的请求长度无限制
c.GET请求的数据可以收藏为书签,POST请求到的数据不可收藏为书签
d.GET请求后,按后退按钮、刷新按钮无影响。POST请求数据会被重新提交
e.GET编码类型:application/x-www-form-url,POST的编码类型有很多种:
encodeapplication/x-www-form-urlencoded
multipart/form-data
f.GET历史参数会被保留在浏览器里,POST不会保存在浏览器中
g.GET只允许ASCII。POST没有编码限制,允许发二进制
h.GET与POST相比,GET安全性较差,因为所发的数据是URL的一部分
# Cookie与Session
- Cookie
1.若我们用JS的变量来存数据,那么在页面关闭的时候,数据就消失了
2.保持登录状态是怎么做到的呢?
按照正常的HTTP协议来说,是做不到的
因为HTTP协议,上下文无关协议。
3.所以说前端页面上,有可以持久化存储数据的东西,一旦登陆成功,就记载在这个里面。这就是Cookie
Cookie是有限制的。
Cookie是存在浏览器里的,不是存在某个页面上的。
Cookie是可以长期存储的。
Cookie即使是保存在浏览器中,也是存放在不同的域名下的。
4.登录百度过程
1).初始状态:没有登陆
2).访问百度的登录,输入用户和密码
3).若用户名和密码是正确的,百度的后端回想这个域名下,设置一个Cookie。写入用户的基本信息(加密的)
4).以后每一次向百度发送请求,浏览器都会自动带上这个Cookie
5).服务端(后端)看到了带有ID的Cookie,就可以解析这个加密的ID,来获取到这个用户本身的ID
6).若能获取到本身的ID,那么就证明这个用户已经登陆过了,所以后端可以继续保留用户的信息。
缺点:若某个坏人,复制了我浏览器里的Cookie,他就可以在他的电脑上登录我的账号了
- Session
1.Session信息是存储在服务器上的,Cookie信息是存储在浏览器上的
数据存在Session上也有缺点:
若用户量非常大,上亿的用户。
在用户量很大的时候,服务端很耗资源
因为后端不止一台服务器,用户的登录信息,一般只存在一台服务器上。
因为用户的登录操作,在哪台机器上执行的,就一般存在哪台机器上。
需要通过反向代理。(轮询,IP哈希)
XSS注入攻击,就是针对Cookie进行的攻击。
- 发送网络请求
1.在浏览器中直接输入网址(无法用代码控制)
2.location.href="url",可以发出网络请求,但是页面会发生跳转(页面会跳转)
3.带有src属性的标签,请求是可以发出的,服务端可以处理的并返回,但是返回后,能否被应用还要看浏览器(页面无法处理返回结果)
4.带有href属性的标签,请求是可以发出的,服务端可以处理的并返回,但是返回后,能否被应用还要看浏览器(页面无法处理返回结果)
5.带有action属性的标签,例如form表单,也可以向后端发出请求,但是form表单发出请求后,也会页面跳转(页面会跳转)
//希望有一种方式,可以用代码控制,页面不会跳转,服务端返回的结果我可以用JS继续处理
6.ajax
```js
//要素
//1.请求方式:GET、POST
//2.url
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{//兼容IE6
xhr = new ActiveXObject("Microsoft.XMLHttp");
}
console.log(xhr.readyState);//0:初始化
xhr.open("get", "
http://developer.duyiedu.com/edu/testAjaxCrossOrigin");
console.log(xhr.readyState);//1:与服务器建立连接
xhr.onreadystatechange = function(){//当readyState改变,执行该函数
//readyState == 4:请求已完成,已接收到数据
//status == 200 网络请求,结果都会有一个状态码,来表示这个请求是否正常。200表示请求成功
//http状态码
//2**:表示成功
//3**:表示重定向
//4**:表示客户端错误,404页面没找到
//5**:表示服务端错误
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.readyState);//2 3 4:请求已完成,已接收到数据
document.getElementById('test').innerText = xhr.responseText;
var data = JSON.parse(xhr.responseText);
console.log(data);
}
}
xhr.send();//若open第三个参数传true,或者不传,为异步模式。若传false为同步模式
```
- 跨域
跨域访问资源
1.哪些东西属于资源?
JS文件算吗?JS文件肯定是资源,但是JS文件是允许被跨域请求的
CSS文件,jpg,png等。src属性的资源都是可以被跨域请求的。href资源大部分都是可以被跨域请求的。
2.哪些资源算是跨域请求的资源
1.后端接口的数据
2.其他域的Cookie
3.其他域的缓存
3.什么是其他的域?怎样算是跨域?
页面本身:有协议(http/https),域名,端口
要请求的数据:
http://www.baidu.com:80
协议,域名,端口号这三个,有任意一个不一样就算跨域。
4.跨域这个行为,发生在哪里?
答案:
1.即使跨域了(协议、域名、端口号不一样),请求也可以发出
2.服务器端也是可以接收的
3.服务器端也是可以正常处理的
4.服务器端也是可以正常返回数据的
5.浏览器也能接收到这些数据
6.接收到之后,发现当前页面的域和请求的域不同,所以判定为跨域
7.我们的代码在这等着结果,但是因为浏览器判定跨域了,uhuibajieguo传递给我们的代码
5.虽然跨域了,但是我们依然需要这个数据,怎么办?
解决跨域问题:
1.后端(别人家的)是否配合我们进行跨域
1.JSONP(正常情况下,返回的数据都是JSON格式,JSONP是一种特殊的格式
2.后端设置Access-Control-Allow-Origin属性以支持跨域
2.后端不配合我们进行跨域
1.iframe(缺点:只能显示,不能控制)
2.通过后端代理(自己的后端)
- JSONP
```js
//jsonp格式哪里特殊?
//1.发送的时候会带上一个参数callback
//2.返回的结果不是json,而是 callback名+(json数据)
$.ajax({
type:'get',
dataType:'jsonp',
success:function(data){
console.log(data);
}
});
//jsonp跨域,只能使用get方法,若我们设置的是POST方法,jQuery会自动转为get方法。
//是不是在jsonp里面我们只能使用get方法?是不是我们设置的POST方法都会转为get方法?
//不是,jQuery会先判断是否同源,若同源,那么设置的是get就是get,设置的POST就是POST;若不是同源,无论设置的是什么,都改为get。
```
- JSONP原理
```js
//想从一个接口获取一个数据
//但是这个接口和当前页面不是同源的。(也就是跨域了)
//但是这个接口是支持JSONP的
//script标签有src属性,可以发出网络请求
//script标签,虽然可以引用其他域的资源,浏览器不限制。但是浏览器会将返回的内容,作为JS代码执行。
//JSONP原理:
//1.判断请求与当前页面的域,是否同源,若同源则发送正常的ajax,就没有跨域的事情了
//2.若不同源,生成一个script标签。在生成一个随机的callback名字
//3.设置script标签的src,设置为要请求的接口
//4.将callback作为参数拼接在后面。
//-------以上是前端部分
//5.后端接受到请求后,开始准备要返回的数据
//6.后端拼接数据,将要返回的数据用callback的值和括号包裹起来
// 例如:callback=asd123456,要返回的数据是{"a":1,"b":2},
// 就要拼接为asd12345({"a":1,"b":2});
//7.将内容返回
//--------以上是后端部分
//8.浏览器接收到内容,会当做js代码执行
//9.从而执行名为asd123456()的方法,这样我们就接收到了后端返回给我们的对象
var $ = {
ajax: function(options){
var url = options.url,
type = options.type,
dataType = options.dataType;
//判断是否同源
//获取目标url的域
var targetProtocol = "";//目标接口的协议
var targetHost = "";//目标接口的host,host是包含域名和端口的
//若url不带http,那么访问的一定是相对路径,相对路径一定是同源的。
if(url.indexOf("http://") == 0) || url.indexOf("https://") == 0){//绝对路径
var targetUrl = new URL(url);
targetProtocol = targetUrl.protocol;
targetHost = targetUrl.host;
}else{//相对路径
targetProtocol = location.protocol;
targetHost = location.host;
}
//首先判断是否为jsonp,因为不是jsonp不用做其他的判断,直接发送ajax
if(dataType == 'jsonp'){
//要看是否同源
if(location.protocol == targetProtocol || location.host == targetHost){
//此处省略。因为同源,jsonp会当做普通的ajax请求
}else{//不同源,跨域
//随机生成一个callback
var callback = "cb" + Math.floor(Math.random() * 1000000);
//给window上添加一个方法
window[callback] = options.success;
//生成script标签
var script = document.createElement("script");
if(url.indexOf("?") > 0){//表示已经有参数了
script.src = url + "&callback=" + callback;
}else{//表示没有参数
script.src = url + "?callback=" + callback;
}
script.id = callback;
document.head.appendChild(script);
}
}
}
}
$.ajax({
type:'get',
dataType:'jsonp',
success:function(data){
console.log(data);
}
})
```
以上是markdown格式的笔记
来源:oschina
链接:https://my.oschina.net/u/4384923/blog/4281459