面试官:ajax是什么?我:啥?这不是JQuery封装的工具方法吗?
正文
不得不说,模拟面试那时候,什么刁钻的问题几乎都接触过,用这种远古问题拷打我,真是。。。绝了。
我还没答上来,真是,绝妙。
AJAX定义
AJAX 代表异步的 JavaScript 和 XML(Asynchronous JavaScript And XML)。
简单点说,就是使用 XMLHttpRequest
对象与服务器通信。它可以使用 JSON、XML (Extensible Markup Language)、HTML 和文本文件等格式发送和接收数据
AJAX 最吸引人的就是它的异步
特性,也就是说它可以在不重新刷新页面的情况下与服务器通信、交换数据或更新页面
整个流程很简单,如下
- 创建一个XMLHttpRequest对象,发送异步请求HttpRequest
- 服务器通过网络,接收HttpRequest请求,返回请求数据
- 浏览器通过网络,接收服务器返回的数据,用JS操作DOM更新页面
为避免混淆,这里重新梳理一下 Ajax 概念:
- AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
- AJAX 不是编程语言,而是一种基于现有标准的新方法
- AJAX 最大的优点是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容
- AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行。
- XMLHttpRequest 只是实现 Ajax 的一种方式
总的来说,AJAX是浏览器与服务器进行数据通信的技术
AJAX实现
URL
URL (Uniform Resource Locator) 统一资源定位符(统一资源定位器、定位地址、URL地址)俗称地址,是因特网上标准的资源的地址,如同在网络上的门牌,用于访问网络上的资源
URL组成:URL 由协议、域名、资源路径组成
- 协议:URL 使用 http 协议(超文本传输协议),规定浏览器与服务器之间传输数据的格式
- 域名:标记服务器在互联网中的方位
- 资源路径:标记资源在浏览器下的具体位置
比如,我们这里架假设要去访问百度网站上的一份文件
1 | http://www.baidu.com/test/helloworld.txt |
这里我们将上述url拆分一下,结果如下
访问协议 | 服务器名称:域名 | 目录名 | 文件名 |
---|---|---|---|
http: | www.baidu.com | test | helloworld.txt |
域名这里如果细说,还要提到IP和端口,这里暂时先跳过,下期再说。
XMLHttpRequest
XHR概念
XMLHttpRequest
(XHR)对象用于与服务器交互。
通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL 来获取数据。
这允许网页在不影响用户操作的情况下,更新页面的局部内容。
XMLHttpRequest
在 AJAX 编程中被大量使用,所有现代浏览器均支持 XMLHttpRequest 对象
XMLHttpRequest
可以用于获取任何类型的数据,而不仅仅是 XML,它甚至支持 HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制
XHR使用
实现 Ajax
异步交互需要完成以下步骤:
- 创建
XMLHttpRequest
对象 - 通过
XMLHttpRequest
对象的open()
方法与服务端建立连接 - 构建请求所需的数据内容,并通过
XMLHttpRequest
对象的send()
方法发送给服务器端 - 通过
XMLHttpRequest
对象提供的readystatechange、loadend
事件监听服务器端的通信状态 - 接受并处理服务端向客户端响应的数据结果
- 将处理结果更新到
HTML
页面中
向服务器发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法
open()
通过
XMLHttpRequest
对象的open()
方法与服务器建立连接语法
1
xhr.open(method, url, [async][, user][, password])
参数说明
参数 说明 method 表示当前的请求方式,常见的有 GET、POST url 服务端地址 async 布尔值,表示是否异步执行操作,默认为 true(异步) user 可选的用户名用于认证用途;默认为 null password 可选的密码用于认证用途,默认为 null
send()
通过
XMLHttpRequest
对象的send()
方法,将客户端页面的数据发送给服务端语法
1
2// body为 XHR 请求中要发送的数据体(string),如果不传递数据则为 null
xhr.send([body])
onreadystatechange
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时(存有 XMLHttpRequest 状态信息)就会触发 readystatechange 事件
以下是 XMLHttpRequest 对象的三个重要的属性:
属性 | 描述 |
---|---|
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化 0:请求未初始化 1:服务器连接已建立 2:请求已接收 3:请求处理中 4:请求已完成,且响应已就绪 |
status | 200:”OK”,404:未找到页面 |
readystatechange 事件被触发四次,分别是:0-1、1-2、2-3、3-4,对应着 readyState 的每个变化
1 | // 旧写法 |
服务器响应
获取 XMLHttpRequest 响应体
1 | function readBody(xhr) { |
XHR使用示例
- GET 请求
1 | const xhr = new XMLHttpRequest() |
- POST 请求
1 | // POST请求,要设置请求头,请求体携带JSON字符串 |
相关概念拓展
请求方式
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
但在以下情况中,请使用 POST 请求:
- 不愿使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
常见 GET 请求
1 | xhr.open("GET", "/try/ajax/demo.php?fname=Henry&lname=Ford", true) |
常见 POST 请求
1 | xhr.open("POST","/try/ajax/demo.php",true) |
POST 方式发送数据,需要设置请求头,并且使用
send
方法传递参数
Content-Type
Content-Type
是 HTTP 头部字段之一,用于指示请求或响应消息的媒体类型
以下是常见的Content-Type
格式:
application/json
:用于传输 JSON 格式的数据application/xml
:用于传输 XML 格式的数据text/plain
:纯文本格式,通常用于普通文本文件text/html
:用于传输 HTML 格式的数据image/jpeg, image/png, image/gif
:用于传输图像数据multipart/form-data
:通常用于上传文件,表单数据会被编码成一系列的部分application/x-www-form-urlencoded
:通常用于发送表单数据,数据会被编码为键值对的形式(表单默认的提交数据的格式)
在 HTTP 协议中,如果未明确指定 Content-Type
头部字段,默认值取决于请求或响应的具体情况:
- 对于请求(Request)
- 对于常见的表单提交,即
application/x-www-form-urlencoded
- 对于通过表单上传文件的情况,即
multipart/form-data
- 对于常见的表单提交,即
- 对于响应(Response)
- 如果服务器响应包含实际的数据,而不仅仅是一条状态码和头部字段,则常见的默认值为
application/octet-stream
,表示二进制流,没有指定具体的数据类型
- 如果服务器响应包含实际的数据,而不仅仅是一条状态码和头部字段,则常见的默认值为
HTTP 协议规范允许在请求和响应中都不设置 Content-Type
头部字段。
在这种情况下,接收方可能需要根据上下文来猜测数据的类型,这可能引入一些不确定性。
推荐在请求和响应中显式地设置 Content-Type
头部字段
FormData
Ajax 操作往往用来传递表单数据。为了方便表单处理,HTML5 新增了一个 FormData 对象,可以模拟表单,特别适用于发送包含文件上传等复杂数据的请求
使用 FormData 可以执行以下步骤:
- 创建一个 FormData 对象
1 | const formData = new FormData() |
- 向 FormData 对象中添加字段
1 | formData.append('username', 'John') |
- 添加文件类型的字段
1 | // 从文件输入框中获取选中的文件, 可以根据实际情况选择获取文件的方式 |
- 将 FormData 对象作为请求的 body 或附加到 XMLHttpRequest 或 fetch 等发送请求的方法中:
1 | const xhr = new XMLHttpRequest() |
以上就将 FormData 数据作为请求的一部分发送给服务器端了
注意事项:
- 当使用 FormData 时,浏览器会自动设置适当的
Content-Type
头部,无需手动设置 - FormData 也支持删除字段和追加相同字段名的多个值等操作,请根据需求使用相应的方法
FormData 对象其他方法参考官网:MDN-FormData
结语
说实话,早年就以为这东西是jquery封装的,结果上次模拟面试被狠狠拷打了一波。
虽然这种远古问题不应该算是关注范围以内的东西了,但是有备无患,这里记录一下。
2024年了,我居然又翻到ajax了,真是。。绝了。
这两天把ajax,axios,fetch相关的请求方式全整理一遍,不然面试还真有点发憷。