来一场实战,ajax和操作dom
什么是ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
百度百科
我的理解比较直接一些,就是向服务端发送数据或者从服务端获取数据。
ajax请求类型与RESTful API
ajax请求类型一般分为4类, POST GET PUT DELETE 。一般使用post和get。
当前后端完全分离以后,服务端只提供ajax接口,一般操作类型就是增改查删(CURD)
假设我们数据库里有一张User表,我们根据表对象模型User,按照restful规范设计的接口应该是这样的:
新增用户:[POST] /users
修改用户:[PUT] /users/id
删除用户:[DELETE] /users/id
查找全部用户:[GET] /users
这样ajax的请求类型就和接口的类型对应起来了,而且非常清晰。
当然不一定非要这么用,只是说这么用比较合适。
发送ajax请求的方式
axios 【插件】
jQuery的ajax 【插件】
ES6中的 fetch
XMLHttpRequest对象
上面的两个插件非常好用,一般情况下我们无需用原生的js去实现,使用插件更加方便。用原生的js来写demo只是为了更好的理解过程。
了解一下Promise
在这个教程里面只说基础的用法,更深入的部分自行学习。ajax是一个典型的异步请求,啥叫异步呢?一般来说代码是一行一行执行,理论上来说是执行完第一行再执行第二行,这个就叫“同步”;如果第一行是异步的话,就是说在执行第二步的时候,第一步并没有执行完成。为了在第二步中能使用第一步中的结果,最早的方式是使用回调,就是把第二步当成一个函数,传给第一步,等第一步执行完成在执行这个函数。如果异步的过程很多的时候,就歇菜了,代码基本很很难阅读和理解,这个就是所谓的“回调地狱”。所以Promise能比较优雅的解决这个问题。
// 用回调的方式function read (cb) {let a = 1setTimeout(() => { // 2秒后完成操作a = 30if (cb) {cb(a)}}, 2000)}read((num) => {console.log(num)})// 用promise的方式function readPromise () {let a = 1return new Promise((resolve) => {setTimeout(() => { // 2秒后完成操作a = 30resolve(a)}, 2000)})}readPromise().then(num => {console.log(num)})
附加说一下,高频面试题:
Promise.all() 可以用来一次执行多个异步任务
Promise.race() 获得先返回的结果
原生的JS来写一个请求的范例
来一个to do list
<!DOCTYPE html><html><head><title>to do list</title></head><body><div><ul id="to-do-list"></ul><button id="add">添加</button></div><script>const id = 'to-do-list'const container = document.querySelector(`#${id}`)const btn = document.querySelector('#add')// ajax请求方法const ajax = (method = 'GET', url, data = {}) => {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest()// 请求成功回调函数xhr.onload = e => {resolve(JSON.parse(xhr.response)) // 将服务端返回的数据返回}// 请求出错xhr.onerror = e => {// 返回错误reject({code: -1,msg: '请求出错'})}// 请求超时xhr.ontimeout = e => {// 返回错误reject({code: -2,msg: '请求超时'})}xhr.open(method, url, true);xhr.send(data)})}// 获取列表ajax('GET', 'http://yapi.totonoo.com/mock/11/list').then(res => {// 这里是成功后执行的操作let html = ''res.data.forEach(item => {// 拼接字符串html += `<li><label><input type="checkbox"> ${item.title}</label></li>`})// 将拼接好的字符串插入到指定的位置container.innerHTML = html}).catch(err => {// 这里是失败后执行的操作alert(err.msg)}).finally(() => {// 完成后执行,不管成功或者失败,只要这一次请求完成了console.log('done)})// 添加事件btn.addEventListener('click', () => {// 表单参数const formData = new FormData()formData.append('username', 'lurenjia');ajax('POST', 'http://yapi.totonoo.com/mock/11/add', formData).then(res => {// 创建DOMconst item = document.createElement('li')// 插入内容item.innerHTML = '<label><input type="checkbox"> 新增的</label>'// 在指定位置的最后插入创建的domcontainer.appendChild(item)}).catch(err => {alert(err.msg)})})</script></body></html>
PUT、DELETE跟上面的类似,可以自己尝试去弄一下,这里就到此为止。
http请求的过程详解
这个实际上就是描述,从用户从浏览器敲入网址之后回车,到浏览器显示页面的过程。
如何解决跨域问题
同源策略限制的表现(网上复制的)
1. Cookie、LocalStorage 和 IndexDB 无法读取
2. DOM 和 Js对象无法获得
3. AJAX 请求不能发送
一般来说前端最常见的表现就是AJAX 请求不能发送,1和2一般没有人在意,也不会有人这么做。
常用解决跨域的方法:
Nginx反向代理
Node中间代理
CORS
document.domain + iframe
推荐顺序从上到下,如果前端使用Node提供http服务,推荐使用第二种方式。3依赖于后端,4我基本已经不怎么用了。
