URL,ajax
一个完整的网址的组成
https://credit.baidu.com:80/bkrcredit/cardList/index.html?fbank=3017&nf=fbank#index
协议https:或http:传输协议就是能够把客户端和服务端通讯的信息进行传递的工具- http超文本传输协议,除了传递文本,还可以传递媒体资源文件以及XML格式的数据
- https更加安全的http,一般设计支付的网站都采用https协议(s:ssl加密传输)
- ftb 问价传输协议,一般用于把本地资源上传到服务器,就是把你的前端资源代码上传到服务器的时候用到的一种传输协议
域名credit.baidu.com端口号80- 端口号0~65535,用端口号来区分同一台服务器上的不同项目,一个端口下可以部署一个项目
- http默认的端口号是80
- https默认的端口号是443
- ftb默认端口号是21
- 如果项目采用的是默认端口号,那我们在写地址的时候可以不加端口号,浏览器在发送请求的时候会帮我们加上
请求资源路径bkrcredit/cardList- 找到请求资源的路径
文件名index.html- 找到具体文件
问号传参,或关键字fbank=3017&nf=fbank- 传递给后台的参数
HASH值#index- 锚点定位
- 给予hash实现路由切换,不同的hash值试下展示不同的组件或者模块
URL,URI,URN
URL
带http或https,是带协议的网址
URN
不带协议
URI
URL和URN的总和,可以说URL和URN都是URI
location和history
history
是当前页面切换的历史记录,里面有当前切换地址的一些信息和操作方法 在history中会有一个存储页面信息的池子,只要你打开了某一个页面不关闭,那当前那个页面的历史记录就会保存在池子中 history自己身上的length代表了当前历史栈中存储了历史页面的个数 还在当前history实例所属类的原型上有go、back·forward方法,forword是前进,后退值back,go可以里面如果传(1)就是前进,如果传(-1)就是后退
location 是当前页面url的信息,是个对象
HTTP状态码
1~5开头的三位数字
- 200 OK成功
- 210 CREATE一般应用于告诉服务器创建一个新文件,最后服务器创建成功后返回状态码
- 204 NO CONTENT对于某些请求(例如PUT或者DELETE)服务器不想处理,可以返回空内容,但是这次请求也是成功的,返回状态吗是204
- 301 永久重定向,一般用于域名的迁移,例如京东网站转移
- 304 设置HTTP的协商缓存
- 400传递给服务器的参数错误
- 401 没有权限访问
- 404 请求地址错误
- 500 服务器的未知错误
- 503 服务器超负荷
DNS解析
当发送请求的时候,先把请求发送到DNS解析服务器(DNS上存储着每一个域名相对应的服务器的IP地址),然后找到当前域名对应的IP地址,然后再向则个IP地址发送请求找到对应的服务器
DNS优化
DNS缓存
一般浏览器会在第一次解析之后,默认建立缓存,时间很短,大概一分钟左右 做DNS预解析dns-prefetch,在页面开始加载的时候,就把当前页面中需要访问的其他域名信息进行提前的DNS解析,以后加载到具体内容的时候就可以不用域名解析了 减少DNS解析次数,一个网站中我们需要发送的请求域名和服务器尽可能的减少
<link rel="dns-prefetch" href="//static.360buyimg.com" />
输入URL以后浏览器做的事
- URL地址解析
- DNS域名解析
- 和服务器建立TCP连接
- 把客户端信息发送给服务器(发送http请求)
- 服务器得到并处理请求(HTTP相应内容)
- 客户端渲染服务器返回的内容
- 和服务器端断开TCP连接
ajax
let xhr = new XMLHttpRequest; // 创建一个ajax
console.log(xhr.readyState,12); // 0 刚刚创建了一个ajax
xhr.open('get','./data.json',true); // 打开一个请求
console.log(xhr.readyState,14); // 1 已经打开了一个请求(配置好了请求)
// params1:请求的方式
// params2:请求的资源链接
// params3:是否同异步,不传默认是true就是异步,传递false就是同步
// 监听当前请求的状态
xhr.onreadystatechange = function(){
console.log(xhr.readyState);
// 如果当前的状态码是2,那就说明已经把响应头接受完毕了
// 如果当前的状态码是3,那说明客户端已经开始接受响应体(如果在状态码是3的时候就获取响应体,那有可能获取的不完全)
// 如果当前的状态码是4,说明客户端已经把响应体接受完毕
// console.log(xhr.getAllResponseHeaders());
console.log(xhr.response);
}
xhr.send(); // 发送一个请求
ajax身上的方法和属性
属性
- xhr.responseURL 如果为URL就是URL不是就是空
- xhr.responseText 如果不是json格式字符串就是空
- xhr.responseXML 如果不是XML就是空
- xhr.response 全部格式都拿得到
- xhr.status 当前请求的HTTP的状态
- xhr.statusText 当前请求的http的状态的描述
- xhr.onreadystatechange 监听readyState
- xhr.timeout 请求超时的时间
- xhr.ontimeout=function(){} 请求超时了执行这个函数
- xhr.readyState 当前请求的步骤
- xhr.withCredentials=true 在跨域请求中是否允许携带资源凭证
方法
- xhr.open()配置
- xhr.send()发送
- xhr.abort()终止
- xhr.getAllResponseHeaders() 获取全部请求头信息
- xhr.getResponseHeader("key")获取单个的请求头信息
- xhr.setRequestHeader("key",value) value会自动转换成字符串,必须要在send之前设置
HTTP请求方式
GET系列
- Delect一般告诉服务器删除某些信息
- HEAD只获取响应头的内容,响应主体内容不要
- OPTIONS试探性的请求,给服务器发送个请求,看看服务器能不能接收到,如果接受到能不能正常的返回
POST系列
- PUT和DELTE是相对应的,告诉服务器要存储某些东西
GET和POST的区别
- GET是在URL后问号传参,POST是在send()内传参,而且只有在send中的数据才叫做请求体
- get传递给服务器的参数要比post少,因为浏览器对url的长度有限制(IE一般是2kb左右,谷歌的限制一般是6到7kb左右)所以一般get用来获取,因为获取不需要传递参数
- post是在()内传参,他没有限制,所以一般用来获取
- get传参相对来说不安全(因为在url中,可以看到),post(在请求体中)相对安全一点,GET相对于POST来说不安全,因为GET请求是基于问号传参,有一种技术就是URL劫持,这样别人就可以拿到你的参数或者篡改你的参数,POST是基于请求体传参的,他相对来说还安全一些
- get请求会产生缓存,如果没一次请求的地址一模一样,这样他就会走缓存
- 如果你不想走缓存,只要保证每一次请求的地址有不一样的地方就可以(一般都是参数)
let flag = Date.now() // 获取时间戳 // 不让这次请求走缓存的办法(flag永远不会重复)
'http://www.baidu.com:8080/index.html?name=9&age=2&flag=' + flag;
利用随机数
let num = Math.random(); // 获取0-1之间的随机小数
console.log(num);
'http://www.baidu.com:8080/index.html?name=9&age=2&flag=' + num;
性能优化的几种方式
- 减少HTTP的请求次数和传输报文的大小
- CSS SPRITE (雪碧图 图片精灵)
- iconFont(字体图标)或者使用SVG的矢量图
- 懒加载
- 取消音视频的预加载
- 客户端与服务端的数据传输尽可能拿JSON格式完成,XML格式要比JSON格式质量大
- 做CDN(地域分布式服务器) 、加服务器
- 图片做base64转码(把图片转化成base64编码,可以减少图片的请求次数,提高页面的渲染速度,但是不利于开发和维护,用webpack可以实现图片的批量base64转化,这个过程也是webpack去做)
/*
* 对Axios的二次封装,目的:把当前项目中,所有请求的公共部分进行统一处理
* + axios.defaults 设置公共的配置项
* + axios.interceptors 基于拦截器做统一处理
*/
// 配置请求接口的统一前缀「webpack环境,我们根据环境变量的值,设置不同的前缀,来区分不同的环境」
// + 开发 development
// + 测试 test
// + 灰度 grayscale
// + 生产 production
// $ npm run build/start/test/gray... 设置不同的环境变量
/* const env = process.env.NODE_ENV || 'development';
switch (env) {
case 'development':
axios.defaults.baseURL = 'http://127.0.0.1:9999';
break;
case 'test':
axios.defaults.baseURL = 'http://168.1.123.1:9999';
break;
case 'production':
axios.defaults.baseURL = 'http://api.zhufengpeixun.cn';
break;
} */
axios.defaults.baseURL = 'http://127.0.0.1:9999';
// 设置超时时间{10S} & 设置跨域请求中是否携带资源凭证
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
// 配置公共的自定义请求头信息 headers['common']/headers['post/get...']/headers/...
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// POST系列请求对于请求主体信息的统一格式化
axios.defaults.transformRequest = function (data, headers) {
if (data === null || typeof data !== "object") return data;
let contentType = headers['Content-Type'] || headers.post['Content-Type'];
if (contentType.includes('urlencoded')) return Qs.stringify(data);
if (contentType.includes('json')) return JSON.stringify(data);
return data;
};
// 设置响应状态码的校验处理{规定服务器返回的状态码哪些是算请求成功,哪些算失败}
axios.defaults.validateStatus = function (status) {
return status >= 200 && status < 400;
};
// 请求拦截器,当所有配置处理完,在向服务器发送请求之前,我们拦截到现有的配置,再去做一些统一修改
axios.interceptors.request.use(function (config) {
// 例如:传递Token
/* const token = sessionStorage.getItem('token');
if (token) {
config.headers['Authorization'] = token;
} */
return config;
});
// 响应拦截器,当前请求有结果之后,我们在业务层自己调用then/catch方法之间拦截一下,这样可以做一些成功或者失败的统一提示处理等...
axios.interceptors.response.use(function onfulfilled(response) {
// 成功:服务器正常返回结果 & validateStatus状态码校验成功
return response.data;
}, function onrejected(reason) {
// 失败:@1服务器返回了结果但是状态码没有经过validateStatus校验 || @2服务器压根没有返回任何的结果 || @3请求中断或者超时...
let response = reason.response;
if (response) {
// @1
switch (response.status) {
case 401:
break;
// ...
}
} else {
if (reason && reason.code === 'ECONNABORTED') {
// @3
}
if (!navigator.onLine) {
// @2
}
}
return Promise.reject(reason);
});
export default axios;