HTTP、存储、Ajax

236 阅读14分钟

前后端通信

  1. 前后端通信 前端和后端数据交互的过程:浏览器和服务器之间数据交互的过程

  2. 后端向前端发送数据 访问页面

  3. 前端向后端发送数据 用户注册

  • 前后端通信的过程与概念解释
  1. 前后端通信的过程 前后端的通信是在‘请求-响应’中完成的

image.png

  1. 概念解释
    前端:浏览器端
    客户端:只要能和服务器通信的就叫客户端
    命令行工具 :curl https:www.imooc.com
    后端:服务器端
  • 前后端的通信方式 1. 使用浏览器访问网页 在浏览器地址栏输入网址,按下回车

2. HTML 的标签 浏览器在解析 HTML 标签的时候,遇到一些特殊的标签,会再次向服务器发送请求
link/img/script/iframe
还有一些标签,浏览器解析的时候,不会向服务器发送请求,但是用户可以使用他们向服务器发送请求
a/form

3. Ajax 和 Fetch

HTTP

初识HTTP

  1. HTTP 超文本传输协议

HTML:超文本标记语言

  • 超文本:原先一个个单一的文本,通过超链接将其联系起来。由原先的单一的文本变成了可无限延伸、扩展的超级文本、立体文本
  • HTML、JS、CSS、图片、字体、音频、视频等等文件,都是通过 HTTP(超文本传输协议) 在服务器和浏览器之间传输
  • 每一次前后端通信,前端需要主动向后端发出请求,后端接收到前端的请求后,可以给出响应
  • HTTP 是一个请求-响应协议
  1. HTTP 请求响应的过程

image.png

HTTP报文

  1. 请求报文和响应报文 浏览器向服务器发送请求时,请求本身就是信息,叫请求报文
    服务器向浏览器发送响应时传输的信息,叫响应报文

  2. HTTP 报文格式

image.png

  • 请求 请求头:起始行+首部 请求体

  • 请求种类 GET 请求,没有请求体,数据通过请求头携带
    POST 请求,有请求体,数据通过请求体携带

  • 响应 响应头:起始行+首部 响应体

HTTP方法

  1. 浏览器发送请求时采用的方法,和响应无关
    GET、POST、PUT、DELETE
    用来定义对于资源采取什么样的操作的,有各自的语义

  2. HTTP 方法的语义

方法用处适用场景
GET获取数据获取资源(文件)
POST创建数据注册
PUT更新数据修改个人信息,修改密码
DELETE删除数据删除一条评论

这些方法虽然有各自的语义,但是并不是强制性的

  1. RESTful 接口设计 一种接口设计风格,充分利用 HTTP 方法的语义

GET和POST方法

  1. 语义 GET:获取数据 POST:创建数据

  2. 发送数据 GET 通过地址在请求头中携带数据 ,能携带的数据量和地址的长度有关系,一般最多就几K

POST 既可以通过地址在请求头中携带数据,也可以通过请求体携带数据 ,能携带的数据量理论上是无限的

携带少量数据,可以使用 GET 请求,大量的数据可以使用 POST 请求

  1. 缓存 GET 可以被缓存,POST 不会被缓存

  2. 安全性 ?username=alex GET 和 POST 都不安全

发送密码或其他敏感信息时不要使用 GET,主要是避免直接被他人窥屏或通过历史记录找到你的密码

HTTP状态码

  1. HTTP 状态码是什么 定义服务器对请求的处理结果,是服务器返回的

  2. HTTP 状态码的语义 1xx:请求正在处理

2xx:成功

3xx: 重定向

  • 301 moved permanenty,永久性重定向,表示资源已被分配了新的 URL
  • 302 found ,临时性重定向,表示资源临时被分配了新的URL
  • 303 see other ,表示资源存在着另一个 URL,应使用GET方法定向获取资源
  • 304 not modified ,表示服务器允许访问资源﹐但因发生请求未满足条件的情况
  • 307 temporary redirect , 临时重定向﹐和302含义相同

4xx:客户端错误

  • 400 bad request ,请求报文存在语法错误
  • 401 unauthorized ,表示发送的请求需要有通过HTTP认证的认证信息
  • 403 forbidden .表示对请求资源的访问被服务器拒绝
  • 404 not found ,表示服务器上没找到请求的资源
  • 408 Request timeout,客户端请求超时
  • 409 confict ,请求的资源可能引起冲突 5xx:服务器错误
  • 500 internal server error ,表示服务器端在执行请求时发生了错误
  • 501 Not Implemented,请求超出服务器能力范围
  • 503 service unavailable ,表示服务器暂时处于超负载或正在停机维护,无法处理
  • 505 http version not supported ,服务器不支持,或者拒绝支持在请求中的使用的HTTP版本 同样是重定向,302是HTTP1.0的状态码,在HTTP1.1版本的时候为了细化302又分出来了303和307 ,303则明确表示客户端应采用get方法获取资源,他会把post请求变成get请求进行重定向;307则会遵照浏览器标准,不会改变post

本地存储

cookie

  1. 初识cookie
  • Cookie 是什么 Cookie 全称 HTTP Cookie,简称 Cookie
    是浏览器存储数据的一种方式
    因为存储在用户本地,而不是存储在服务器上,是本地存储
    一般会自动随着浏览器每次请求发送到服务器端
  • Cookie 有什么用 利用 Cookie 跟踪统计用户访问该网站的习惯,比如什么时间访问,访问了哪些页面,在每个网页的停留时间等
  • 在浏览器中操作 Cookie 不要在 Cookie 中保存密码等敏感信息
  1. cookie的基本用法
  • 写入 Cookie document.cookie = 'username=zs';
    document.cookie = 'age=18';
    不能一起设置,只能一个一个设置
  • 读取 Cookie console.log(document.cookie); //username=zs;age=18 读取的是一个由名值对构成的字符串,每个名值对之间由“; ”(一个分号和一个空格)隔开
  1. cookie的属性
  • Cookie 的名称(Name)和值(Value) 最重要的两个属性,创建 Cookie 时必须填写,其它属性可以使用默认值
    Cookie 的名称或值如果包含非英文字母,则写入时需要使用 encodeURIComponent() 编码,读取时使用 decodeURIComponent() 解码
document.cookie = `username=${encodeURIComponent('张三')}`;

一般名称使用英文字母,不要用中文,值可以用中文,但是要编码

  • 失效(到期)时间 对于失效的 Cookie,会被浏览器清除
    如果没有设置失效(到期)时间,这样的 Cookie 称为会话 Cookie
    它存在内存中,当会话结束,也就是浏览器关闭时,Cookie 消失
    想长时间存在,设置 Expires 或 Max-Age
    expires
    值为 Date 类型
document.cookie = `username=alex; expires=${new Date(
         '2100-1-01 00:00:00'
 )}`;

max-age
值为数字,表示当前时间 + 多少秒后过期,单位是秒
如果 max-age 的值是 0 或负数,则 Cookie 会被删除
document.cookie = 'username=alex; max-age=0';

以下几点了解即可

  • Domain 域
    Domain 限定了访问 Cookie 的范围(不同域名) 使用 JS 只能读写当前域或父域的 Cookie,无法读写其他域的 Cookie

  • Path 路径 Path 限定了访问 Cookie 的范围(同一个域名下)
    使用 JS 只能读写当前路径和上级路径的 Cookie,无法读写下级路径的 Cookie
    document.cookie = 'username=alex; path=/course/list';
    document.cookie = 'username=alex; path=/1.Cookie/';
    当 Name、Domain、Path 这 3 个字段都相同的时候,才是同一个 Cookie

  • HttpOnly 设置了 HttpOnly 属性的 Cookie 不能通过 JS 去访问

  • Secure 安全标志 Secure 限定了只有在使用了 https 而不是 http 的情况下才可以发送给服务端
    Domain、Path、Secure 都要满足条件,还不能过期的 Cookie 才能随着请求发送到服务器端

  1. cookie的封装(在vscode代码中)

  2. cookie的注意事项

  • 前后端都可以创建 Cookie
  • Cookie 有数量限制 每个域名下的 Cookie 数量有限
    当超过单个域名限制之后,再设置 Cookie,浏览器就会清除以前设置的 Cookie
  • Cookie 有大小限制 每个 Cookie 的存储容量很小,最多只有 4KB 左右

localstorage

  1. localStorage 是什么 localStorage 也是一种浏览器存储数据的方式(本地存储),它只是存储在本地,不会发送到服务器端
    单个域名下的 localStorage 总大小有限制

  2. localStorage 的基本用法 console.log(localStorage);

  • setItem() localStorage.setItem('username', 'alex');
  • length console.log(localStorage.length);
  • getItem() console.log(localStorage.getItem('username'));
  • 获取不存在的返回 null
  • removeItem() localStorage.removeItem('username'); 删除不存在的 key,不报错 localStorage.removeItem('name');
  • clear() localStorage.clear();
  1. 使用 localStorage 实现自动填充
      const loginForm = document.getElementById('login');
      const btn = document.getElementById('btn');

      const username = localStorage.getItem('username');
      if (username) {
        loginForm.username.value = username;
      }

      btn.addEventListener(
        'click',
        e => {
          e.preventDefault();
          // 数据验证

          // console.log(loginForm.username.value);

          localStorage.setItem('username', loginForm.username.value);

          loginForm.submit();
        },
        false
      );

总结,cookie、localstorage、sessionStorage三者的异同

  1. 生命周期
  • cookie:可设置失效时间,没有设置的话,默认是关闭浏览器后失效
  • localStorage:除非被手动清除,否则将会永久保存。
  • sessionStorage: 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除。
  1. 存放数据大小
  • cookie:4KB左右
  • localStorage和sessionStorage:可以保存5MB的信息。
  1. http请求
  • cookie:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
  • localStorage和sessionStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信
  1. 易用性
  • cookie:需要程序员自己封装,源生的Cookie接口不友好
  • localStorage和sessionStorage:源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

Ajax

Ajax基础

  1. Ajax 是什么 Ajax 是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML)的简写
  • Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据

  • XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式,XML 现在已经不怎么用了,现在比较常用的是 JSON

  • Ajax 其实就是浏览器与服务器之间的一种异步通信方式 使用 Ajax 可以在不重新加载整个页面的情况下,对页面的某部分进行更新
    例:注册界面

  1. 搭建 Ajax 开发环境 Ajax 需要服务器环境,非服务器环境下,很多浏览器无法正常使用 Ajax
    Live Server在vscode中安装本地环境

Ajax的基本用法

  1. XMLHttpRequest
  • Ajax 想要实现浏览器与服务器之间的异步通信,需要依靠 XMLHttpRequest,它是一个构造函数 不论是 XMLHttpRequest,还是 Ajax,都没有和具体的某种数据格式绑定
  1. Ajax 的使用步骤 2.1. 创建 xhr 对象
    const xhr = new XMLHttpRequest();

2.2. 监听事件,处理响应
当获取到响应后,会触发 xhr 对象的 readystatechange 事件,可以在该事件中对响应进行处理

      xhr.addEventListener('readystatechange', () => {}, fasle);

      xhr.onreadystatechange = () => {
        if (xhr.readyState !== 4) return;

        if ((xhr.status >= 200) & (xhr.status < 300) || xhr.status === 304) {
          // console.log('正常使用响应数据');
          console.log(xhr.responseText);
        }
      };

readystatechange 事件也可以配合 addEventListener 使用,不过要注意,IE6~8 不支持 addEventListener
为了兼容性,readystatechange 中不使用 this,而是直接使用 xhr
由于兼容性的原因,最好放在 open 之前

  • readystatechange 事件监听 readyState 这个状态的变化 它的值从 0 ~ 4,一共 5 个状态
    0:未初始化。尚未调用 open()
    1:启动。已经调用 open(),但尚未调用 send()
    2:发送。已经调用 send(),但尚未接收到响应
    3:接收。已经接收到部分响应数据
    4:完成。已经接收到全部响应数据,而且已经可以在浏览器中使用了

2.3. 准备发送请求

      xhr.open(
        'HTTP 方法 GET、POST、PUT、DELETE',
        '地址 URL https://www.imooc.com/api/http/search/suggest?words=js ./index.html ./index.xml ./index.txt',
        true
      );

调用 open 并不会真正发送请求,而只是做好发送请求前的准备工作

2.3. 发送请求
调用 send() 正式发送请求
send() 的参数是通过请求体携带的数据

  1. 使用 Ajax 完成前后端通信
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

      const xhr = new XMLHttpRequest();
      xhr.onreadystatechange = () => {
        if (xhr.readyState !== 4) return;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
          console.log(xhr.responseText);
          //{"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}
          console.log(typeof xhr.responseText);  //string
        }
      };
      xhr.open('GET', url, true);
      xhr.send(null);

GET请求

  1. 携带数据 GET 请求不能通过请求体携带数据,但可以通过请求头携带
    xhr.send('sex=male');不会报错,但不会发送数据

2. 数据编码
如果携带的数据是非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题
可以使用 encodeURIComponent() 编码

POST请求

  1. 携带数据 POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
  • 如果想发送数据,直接写在 send() 的参数位置,一般是字符串 xhr.send('username=alex&age=18');
  • 不能直接传递对象,需要先将对象转换成字符串的形式
    xhr.send({username: 'alex',age: 18 });
  1. 数据编码
xhr.send(`username=${encodeURIComponent('张三')}&age=18`);

JSON

  1. JSON是Ajax发送和接受数据的一种格式 JSON 全称是 JavaScript Object Notation
    {"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}

  2. 为什么需要 JSON
    JSON 有 3 种形式,每种形式的写法都和 JS 中的数据类型很像,可以很轻松的和 JS 中的数据类型互相转换

  • JS->JSON->PHP/Java
  • PHP/Java->JSON->JS

JSON的三种形式

  1. 简单值形式 .json
    JSON 的简单值形式就对应着 JS 中的基础数据类型: 数字、字符串、布尔值、null
  • 注意事项
    ① JSON 中没有 undefined 值
    ② JSON 中的字符串必须使用双引号
    ③ JSON 中是不能注释的
  1. 对象形式 JSON 的对象形式就对应着 JS 中的对象
  • 注意事项
    JSON 中对象的属性名必须用双引号,属性值如果是字符串也必须用双引号
    JSON 中只要涉及到字符串,就必须使用双引号
    不支持 undefined
  1. 数组形式 JSON 的数组形式就对应着 JS 中的数组
  • 注意事项
    数组中的字符串必须用双引号
    JSON 中只要涉及到字符串,就必须使用双引号
    不支持 undefined
    xhr.open('GET', './arr.json', true);

JSON的常用方法

  1. JSON.parse() JSON.parse() 可以将 JSON 格式的字符串解析成 JS 中的对应值
    一定要是合法的 JSON 字符串,否则会报错

  2. JSON.stringify() JSON.stringify() 可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串

  console.log(
        JSON.stringify({
          username: 'alex',
          age: 18
        })
      );  //{username:'alex',age:18}
  1. 使用 JSON.parse() 和 JSON.stringify() 封装 localStorage

跨域

  1. 跨域是什么

同域,不是跨域 const url = './index.html';

  http://127.0.0.1:5500

不同域,跨域,被浏览器阻止 const url = 'www.imooc.com'; const xhr = new XMLHttpRequest();

  Access to XMLHttpRequest at 'https://www.imooc.com/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
不同域之间的请求,就是跨域请求

  1. 什么是不同域,什么是同域 https(协议)://www.imooc.com(域名):443(端口号)/course/list…

协议、域名、端口号,任何一个不一样,就是不同域
与路径无关,路径一不一样无所谓

  不同域
  https://www.imooc.com:443/course/list
  http://www.imooc.com:80/course/list

  http://www.imooc.com:80/course/list
  http://m.imooc.com:80/course/list
  http://imooc.com:80/course/list

  同域
  http://imooc.com:80
  http://imooc.com:80/course/list

3. 跨域请求为什么会被阻止 阻止跨域请求,其实是浏览器本身的一种安全策略--同源策略
其他客户端或者服务器都不存在跨域被阻止的问题

  1. 跨域解决方案
    ① CORS 跨域资源共享
    ② JSONP

优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP

CORS跨域资源共享

  1. CORS 是什么
  • Access-Control-Allow-Origin: * 表明允许所有的域名来跨域请求它,* 是通配符,没有任何限制

  • 只允许指定域名的跨域请求
    Access-Control-Allow-Origin: http://127.0.0.1:5500

  1. 使用 CORS 跨域的过程 (了解)
    ① 浏览器发送请求
    ② 后端在响应头中添加 Access-Control-Allow-Origin 头信息
    ③ 浏览器接收到响应
    ④ 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了
    ⑤ 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问
    ⑥ 如果允许跨域,通信圆满完成
    ⑦ 如果没找到或不包含想要跨域的域名,就丢弃响应结果

  2. CORS 的兼容性 IE10 及以上版本的浏览器可以正常使用 CORS

JSONP

  1. JSONP 的原理 script 标签跨域不会被浏览器阻止
    JSONP 主要就是利用 script 标签,加载跨域文件

  2. 使用 JSONP 实现跨域 服务器端准备好 JSONP 接口
    www.imooc.com/api/http/js…

手动加载 JSONP 接口或动态加载 JSONP 接口

       const script = document.createElement('script');
      script.src =
        'https://www.imooc.com/api/http/jsonp?callback=handleResponse';
      document.body.appendChild(script);

      // 声明函数
      const handleResponse = data => {
        console.log(data);
      };

XHR对象

属性

  1. responseType 和 response 属性 responseText 只能在没有设置 responseType 或者 responseType = '' 或 'text' 的时候才能使用
      xhr.open('GET', url, true);

      // xhr.responseType = '';
      // xhr.responseType = 'text';
      xhr.responseType = 'json';
      xhr.send(null);

IE6~9 不支持,IE10 开始支持

  1. timeout 属性 设置请求的超时时间(单位 ms)
    (在xhr.open()之后) xhr.timeout = 10000;
    IE6~7 不支持,IE8 开始支持

  2. withCredentials 属性 指定使用 Ajax 发送请求时是否携带 Cookie
    使用 Ajax 发送请求,默认情况下,同域时,会携带 Cookie;
    跨域时,不会
    xhr.withCredentials = true;
    最终能否成功跨域携带 Cookie,还要看服务器同不同意
    IE6~9 不支持,IE10 开始支持

方法

1. abort() 终止当前请求
一般配合 abort 事件一起使用 (在xhr.send()之后) xhr.abort();

  1. setRequestHeader() 可以设置请求头信息 xhr.setRequestHeader(头部字段的名称, 头部字段的值);
    (在xhr.open()之后)
    请求头中的 Content-Type 字段用来告诉服务器,浏览器发送的数据是什么格式的
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-Type', 'application/json');

事件

  1. load 事件 响应数据可用时触发
      xhr.addEventListener(
        'load',
        () => {
          if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
            console.log(xhr.response);
          }
        },
        false
      );

IE6~8 不支持 load 事件

  1. error 事件 请求发生错误时触发
      xhr.addEventListener(
        'error',
        () => {
          console.log('error');
        },
        false
      );

IE10 开始支持

  1. abort 事件 调用 abort() 终止请求时触发
      xhr.addEventListener(
        'abort',
        () => {
          console.log('abort');
        },
        false
      );
      xhr.open('GET', url, true);
      xhr.send(null);

      xhr.abort();

IE10 开始支持

  1. timeout 事件 请求超时后触发
      xhr.addEventListener(
        'timeout',
        () => {
          console.log('timeout');
        },
        false
      );
      xhr.open('GET', url, true);
      xhr.timeout = 10;
      xhr.send(null);

IE8 开始支持

Ajax进阶

FormData

  1. 使用 Ajax 提交表单

  2. FormData 的基本用法 通过 HTML 表单元素创建 FormData 对象

      const fd = new FormData(表单元素);
      xhr.send(fd);

      通过 append() 方法添加数据
      const fd = new FormData(表单元素);
      fd.append('age', 18);
      fd.append('sex', 'male');
      xhr.send(fd);

IE10 及以上可以支持

(待补充)

Ajax扩展

axios

  1. axios 是什么 axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
    第三方 Ajax 库

www.axios-js.com/zh-cn/docs/

  1. axios 的基本用法 引入 axios
      const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
      axios(url, {
        method: 'post',

        // 请求时的头信息
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
          // 'Content-Type': 'application/json'
        },

        // 通过请求头携带的数据
        params: {
          username: 'alex'
        },

        // 通过请求体携带的数据

        // application/json
        // data: {
        //   age: 18,
        //   sex: 'male'
        // }

        // application/x-www-form-urlencoded
        data: 'age=18&sex=male'

        // timeout: 10

        // withCredentials: true
      })
        .then(response => {
          console.log(response);
          console.log(response.data.data);
        })
        .catch(err => {
          console.log(err);
        });

      axios
        .get(url, {
          params: {
            username: 'alex'
          }
        })
        .then(response => {
          console.log(response);
        });

      axios
        .post(url, 'username=alex&age=18')
        .then(response => {
          console.log(response);
        })
        .catch(err => {
          console.log(err);
        });

Fetch

Ajax应用

(待补充)