URL,ajax

464 阅读9分钟

URL,ajax

一个完整的网址的组成

https://credit.baidu.com:80/bkrcredit/cardList/index.html?fbank=3017&nf=fbank#index
  1. 协议 https:或http:传输协议就是能够把客户端和服务端通讯的信息进行传递的工具
    • http超文本传输协议,除了传递文本,还可以传递媒体资源文件以及XML格式的数据
    • https更加安全的http,一般设计支付的网站都采用https协议(s:ssl加密传输)
    • ftb 问价传输协议,一般用于把本地资源上传到服务器,就是把你的前端资源代码上传到服务器的时候用到的一种传输协议
  2. 域名 credit.baidu.com
  3. 端口号 80
    • 端口号0~65535,用端口号来区分同一台服务器上的不同项目,一个端口下可以部署一个项目
    • http默认的端口号是80
    • https默认的端口号是443
    • ftb默认端口号是21
    • 如果项目采用的是默认端口号,那我们在写地址的时候可以不加端口号,浏览器在发送请求的时候会帮我们加上
  4. 请求资源路径bkrcredit/cardList
    • 找到请求资源的路径
  5. 文件名index.html
    • 找到具体文件
  6. 问号传参,或关键字fbank=3017&nf=fbank
    • 传递给后台的参数
  7. 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以后浏览器做的事

  1. URL地址解析
  2. DNS域名解析
  3. 和服务器建立TCP连接
  4. 把客户端信息发送给服务器(发送http请求)
  5. 服务器得到并处理请求(HTTP相应内容)
  6. 客户端渲染服务器返回的内容
  7. 和服务器端断开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身上的方法和属性

属性
  1. xhr.responseURL 如果为URL就是URL不是就是空
  2. xhr.responseText 如果不是json格式字符串就是空
  3. xhr.responseXML 如果不是XML就是空
  4. xhr.response 全部格式都拿得到
  5. xhr.status 当前请求的HTTP的状态
  6. xhr.statusText 当前请求的http的状态的描述
  7. xhr.onreadystatechange 监听readyState
  8. xhr.timeout 请求超时的时间
  9. xhr.ontimeout=function(){} 请求超时了执行这个函数
  10. xhr.readyState 当前请求的步骤
  11. xhr.withCredentials=true 在跨域请求中是否允许携带资源凭证
方法
  1. xhr.open()配置
  2. xhr.send()发送
  3. xhr.abort()终止
  4. xhr.getAllResponseHeaders() 获取全部请求头信息
  5. xhr.getResponseHeader("key")获取单个的请求头信息
  6. xhr.setRequestHeader("key",value) value会自动转换成字符串,必须要在send之前设置

HTTP请求方式

GET系列

  1. Delect一般告诉服务器删除某些信息
  2. HEAD只获取响应头的内容,响应主体内容不要
  3. OPTIONS试探性的请求,给服务器发送个请求,看看服务器能不能接收到,如果接受到能不能正常的返回

POST系列

  1. PUT和DELTE是相对应的,告诉服务器要存储某些东西

GET和POST的区别

  1. GET是在URL后问号传参,POST是在send()内传参,而且只有在send中的数据才叫做请求体
  2. get传递给服务器的参数要比post少,因为浏览器对url的长度有限制(IE一般是2kb左右,谷歌的限制一般是6到7kb左右)所以一般get用来获取,因为获取不需要传递参数
  3. post是在()内传参,他没有限制,所以一般用来获取
  4. get传参相对来说不安全(因为在url中,可以看到),post(在请求体中)相对安全一点,GET相对于POST来说不安全,因为GET请求是基于问号传参,有一种技术就是URL劫持,这样别人就可以拿到你的参数或者篡改你的参数,POST是基于请求体传参的,他相对来说还安全一些
  5. 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;

性能优化的几种方式

  1. 减少HTTP的请求次数和传输报文的大小
  2. CSS SPRITE (雪碧图 图片精灵)
  3. iconFont(字体图标)或者使用SVG的矢量图
  4. 懒加载
    • 取消音视频的预加载
    • 客户端与服务端的数据传输尽可能拿JSON格式完成,XML格式要比JSON格式质量大
  5. 做CDN(地域分布式服务器) 、加服务器
  6. 图片做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;