原生Ajax
Ajax简介
- Ajax全程为Asynchronous JavaScript + XML,就是异步的JS和XML
- 通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势是:无刷新获取数据,实现局部刷新
- Ajax是一种用于创建快速动态网页的技术
- AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
Ajax 的应用场景
- 页面上拉加载更多数据
- 列表数据无刷新分页
- 表单项离开焦点数据验证
- 搜索框提示文字下拉列表
Ajax的作用、优缺点
作用:ajax用来与后台交互
优点:
- 最大的优点就是可以实现页面无刷新更新数据,在页面内与服务器通信,提高用户浏览网站应用的体验。
- 使用异步的方式与服务器通信,不需要中断操作。
- 可以把以前服务器负担的工作转嫁给客户端,减轻服务器和带宽,可以最大程度减少冗余请求。
- 基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
缺点:
- Ajax干掉了Back和History功能,即对浏览器机制的破坏, 无法使用浏览器前进后退。
- 安全问题:跨站脚本攻击、SQL注入攻击等。
- 对搜索引擎的支持比较弱。如果使用不当,AJAX会增大网络数据的流量,从而降低整个系统的性能。
json字符串转换集json对象、json对象转换json字符串
字符串转对象
JSON.parse(json)
eval('(' + jsonstr + ')')
对象转字符串
JSON.stringify(json)
ajax请求如何取消
(1)原生xhr取消请求
var xhr = new XMLHttpRequest();
xhr.abort();
-
AJAX的出现与跨域处理
XMLHttpRequestJSONAJAXCORS四个名词来开会
如何发请求
5种发起请求的方式,主流的、非主流的。
| 何种方式 | 请求方法 | |
|---|---|---|
最常见的form表单 | 默认GET,多用POST,只此两种 | 会刷新页面或者新开页面 |
a 标签 | GET请求 | 也会刷新页面或者新开页面 |
img的src属性 | GET | 只能以图片的形式展现 |
link标签 | GET | 只能以CSS、favicon的形式展现 |
script标签 | GET | 只能以脚本的形式运行 |
可是
- 我们可能想用
GETPOSTPUTDELETE方法 - 不想刷新整个页面,想用一种更易于理解的方式来响应
AJAX出现
浏览器和服务器交互模式 V1.0
在AJAX未出现之前,浏览器想从服务器获得资源,注意是获取资源,会经过如下一个过程
- 浏览器发起请求->服务器接到请求响应给你HTML文档->浏览器收到资源,刷新页面,加载获得的的HTML。简略的过程
交互模式2.0
既然AJAX是一系列的技术的组合体,接下来认识一下其中的几位主角
XMLHttpRequest
XMLHttpRequest对象是用来在浏览器和服务器之间传输数据的。
古代的操作的是:
- 浏览器构造
XMLHttpRequest实例化对象 - 用这个对象发起请求
- 服务器响应一个
XML格式的字符串,是字符串,是字符串,是字符串,也就是说响应的第四部分是字符串。 - JS解析符合XML格式的字符串,更新局部页面。
什么是XML,可扩展标记语言。
XMLHttpRequest实例的详解
正如上面的前端代码片段写的一样,主要用到了open() send()方法, onreadystatechange readyState 属性。
-
request.open(method, URL, async)方法。
- 一般用三个参数,第一个参数是请求的方法,可以用
GET POST DELETE PUT等等,URL是用访问的路径,async是是否使用同步,默认true,开启异步,不需要做修改即可,所以实际中只写前两个参数
- 一般用三个参数,第一个参数是请求的方法,可以用
- 如果非要写false,开启同步,会对浏览器有阻塞效应,而且如果值为false,则send()方法不会返回任何东西,直到接受到了服务器的返回数据
-
request.send()方法。
- 发送请求. 如果该请求是异步模式(默认),该方法会立刻返回. 相反,如果请求是同步模式,则直到请求的响应完全接受以后,该方法才会返回
-
readyState属性。-
描述请求的五个状态。
- 0 === 常量
UNSENT(未打开) open()方法未调用 - 1 ===
OPENED(未发送) 只是open()方法调用了 - 2 ===
HEADERS_RECEIVED (已获取响应头)send()方法调用了,响应头和响应状态已经返回了 - 3 ===
LOADING (正在下载响应体)响应体下载中,responseText已经获取了部分数据 - 4 ===
DONE (请求完成)整个响应过程完毕了。 这个值是实际中用到的。 - 只要不等于4,就表示请求还在进行中。
- 0 === 常量
-
-
responseText属性是此次响应的文本内容。 -
onreadystatechange属性。readyState属性的值发生改变,就会触发readyStateChange事件。- 我们可以通过
onReadyStateChange属性,指定这个事件的回调函数,对不同状态进行不同处理。尤其是当状态变为4的时候,表示通信成功,这时回调函数就可以处理服务器传送回来的数据。即前面的代码片段的处理方式。
习惯用javaScript的前端是不想和XML打交道的,应该用一种符合js风格的数据格式语言。
JSON
它是一门全新的数据交换语言,不是JavaScript的子集。
JSON很简单,数据类型和JS有点不同的地方。
| JavaScript | JSON |
|---|---|
| string | "string" 必须写双引号 |
| number | number |
| object | {"object": "name"} 必须双引号 |
| undefined | 没有 |
| null | null |
| boolean | 直接写true false |
| array | array |
| function | 没有 |
| variable |
- 浏览器的全局对象
window上有JSON对象,直接使用window.JSON.parse(string)
let string = request.responseText
let json = window.JSON.parse(string) //string 要符合JSON的格式
以上是JSON解析部分的代码。
此时服务器端代码是
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.write(`
{
"note" : {
"to" : "木木",
"from" : "少少",
"heading" : "你好哇",
"content" : "好久不见啊"
}
}
`)
CORS
- 如果
AJAX向非同源的地址发起请求,会报错。
- 这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200,也就是说即使你看到了200的正确码,也没有用
- 但是form表单无视同源政策,可以发起跨域请求。
<button id="myButton">点我</button>
<form action="https://www.baidu.com" method="get">
<input type="password" name="password">
<input type="submit" value="提交">
</form>
上述请求响应都没有问题
然而对于AJAX就不行
...
request.open('GET', 'http://www.baidu.com')
...
- 这是为什么呢,因为
原页面用 form 提交到另一个域名之后,原页面的脚本无法获取新页面中的内容,所以浏览器认为这是安全的。
而 AJAX 是可以读取响应内容的,因此浏览器不能允许你这样做。如果你细心的话你会发现,其实请求已经发送出去了,你只是拿不到响应而已。
所以浏览器这个策略的本质是,一个域名的 JS ,在未经允许的情况下,不得读取另一个域名的内容。但浏览器并不阻止你向另一个域名发送请求。作者:方应杭
链接:https://www.zhihu.com/question/31592553/answer/190789780
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
那么如何让AJAX跨域发起请求呢。
答案是CORS
CORS目前是W3C的标准,它允许浏览器跨域发起XMLHttpRequest请求,而且可以发起多种请求,不像JSONP只能发起GET请求,全称是"跨域/源资源共享"(Cross-origin resource sharing)。
- 如果想要发起跨域请求 例如: http://wushao.com:8001 要想访问 http://shaolin.com:8002,可以做如下处理
request.open('GET', 'http://wushao.com:8001/xxx') //配置request
- 服务器端的代码需要做如下处理
response.setHeader('Access-Control-Allow-Origin', 'http://shaolin.com:8002')
一定要注意是谁去访问谁,8001去访问8002,那么8001的前端代码要告诉8002的后端代码,咱们是一家人,你和浏览器说说别让它禁我了。
获得请求和响应头
- 获得请求头的方法
request.open('GET', 'http://shaolin.com:8002/xxx')// 请求的第一部分
request.setRequestHeader('Content-Type', 'x-www-form-urlencoded')//请求的第二部分
request.setRequestHeader('wushao', '18') //请求的第二部分
request.send('我要设置请求的第四部分') //请求的第四部分
request.send('name=wushao&password=wushao') //请求的第四部分
对应的典型的http请求四部分
GET /xxx HTTP/1.1
HOST: http://shaolin.com:8002
Content-Type: x-www-form-urlencoded
wushao: 18
name=wushao&password=wushao
- 获得响应的方法
request.status //响应的第一部分 200
request.statusText //响应的第一部分 OK
request.getAllResponseHeaders //响应的第二部分,这个方法好啊,全部的响应头
request.getResponseHeader('Content-Type') //响应的第二部分具体的
request.responseText //响应的第四部分
对应的典型的http响应的四部分
HTTP/1.1 200 OK
Content-Type: text/json;charset=utf-8
{
"note" : {
"to" : "木木",
"from" : "少少",
"heading" : "你好哇",
"content" : "好久不见啊"
}
}
回顾一下各个status对应的意思
100
200 === OK,请求成功
301 === 被请求的资源已永久移动到新位置
302 === 请求临时重定向,要求客户端执行临时重定向
304 === 和上次请求一样,未改变
403 === 服务器已经理解请求,但是拒绝访问
404 === 请求失败,服务器上没有这个资源
502 === 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503 === Service Unavailable 由于临时的服务器维护或者过载,服务器当前无法处理请求。
转载自:
-
手写Ajax原始请求
//1.创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
//2.规定请求的类型、URL 以及是否异步处理请求。
xhr.open('GET',url,true); //默认true,开启异步,不需要做修改即可,所以实际中只写前两个参数
//3.发送信息至服务器时内容编码类型
//设置响应头
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//4.发送请求
xhr.send(null);
//5.接受服务器响应数据
xhr.onreadystatechange = function () {
if(xhr.readyState ===4){
//判断响应状态码 200 404 403 401 500
//2xx 成功
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.responseText);
}else{
}
}
}
| 区别描述 | onload事件 | onreadystatechange事件 |
| 是否兼容IE低版本 | 不兼容 | 兼容 |
| 是否需要判断Ajax状态码 | 不需要 | 需要 |
| 被调用次数 | 一次 | 多次 |
• 将原生的 ajax 封装成 promise
var myNewAjax = function (url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest(); //创建Ajax对象
xhr.open('get', url, true); //告诉浏览器以什么方式发送请求 以及请求发送到哪
xhr.send(data); //发送请求
xhr.onreadystatechange = function () { //设置响应服务器端数据处理
if (xhr.status == 200 && readyState == 4) {
var json = JSON.parse(xhr.responseText);
resolve(json)
}
else if(xhr.readyState == 4 && xhr.status != 200)
{
reject('error');
}
}
})
}
readyState==4是什么意思?
1、在ajax中有状态码readyState,readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义
0:未初始化,XMLHttpRequest对象还没有完成初始化
1:载入,XMLHttpRequest对象开始发送请求
2:载入完成,XMLHttpRequest对象的请求发送完成
3:解析,XMLHttpRequest对象开始读取服务器的响应
4:完成,XMLHttpRequest对象读取服务器响应结束
所以说readyState == 4表示已经完成了ajax请求。
2、open函数最后一个参数设置为布尔值true表示向服务器发送的请求是异步的。也就说代码执行send方法后,不会在此处一直等待服务器执行的结果,而是继续往后执行后面的代码。
• ajax 状态码
xhr.readyState // 获取Ajax状态码
0 - (未初始化)还没有调用 send()方法
1 - (载入)已调用 send()方法,正在发送请求
对比题
1.Ajax、Fetch、Axios三者的区别?
- ajax是js异步技术的术语,早起相关的api是xhr,它是一个术语
- fetch是es6新增的用于网络请求标准api,它是一个api
- axios是用于网络请求的第三方库,它是一个库
-
Ajax有几种请求方式?它们的优缺点?
常用的post,get,delete。不常用copy、head、link等等。
a.代码上的区别
(1)get通过url传递参数
(2)post设置请求头 规定请求数据类型
b.使用上的区别
(1)post比get安全 ,(因为post参数在请求体中。get参数在url上面)
(2)get传输速度比post快 根据传参决定的。(post通过请求体传参,后台通过数据流接收。速度稍微慢一些。而get通过url传参可以直接获取)
(3)post传输文件大理论没有限制, get传输文件小大概7-8k ie4k左右;
(4)get获取数据 post上传数据,(上传的数据比较多 而且上传数据都是重要数据。所以不论在安全性还是数据量级 post是最好的选择)。
• GET 和 POST 的区别
参考回答:
- get 参数通过 url 传递,post 放在 request body 中。
- get 请求在 url 中传递的参数是有长度限制的,而 post 没有。
- get 比 post 更不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息。
- get 请求只能进行 url 编码,而 post 支持多种编码方式 get 请求会浏览器主动 cache,而post 支持多种编码方式。
- get 请求参数会被完整保留在浏览历史记录里,而 post 中的参数不会被保留。
- GET 和 POST 本质上就是 TCP 链接,并无差别。但是由于 HTTP 的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。GET 和 POST 的底层也是 TCP/IP,GET/POST 都是 TCP 链接。
- GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应200(返回数据);而对于 POST,浏览器先发送 header,服务器响应 100 continue,浏览器再发送data,服务器响应 200 ok(返回数据)。
一、功能不同
1、get是从服务器上获取数据。GET - 从指定的资源请求数据。
2、post是向服务器传送数据。POST - 向指定的资源提交要被处理的数据。
二、过程不同
1、get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。
2、post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
三、获取值不同
1、对于get方式,服务器端用Request.QueryString获取变量的值。
2、对于post方式,服务器端用Request.Form获取提交的数据。
四、传送数据量不同
1、get传送的数据量较小,不能大于2KB。
2、post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
-
假如我有多个请求,我需要让这些 ajax 请求按照某种顺序一次执行,有什么办法呢?
递归+promise:
//按顺序执行多个ajax命令,因为数量不定,所以采用递归
function send(action, arg2) {
//将多个命令按顺序封装成数组对象,递归执行
//利用了deferred对象控制回调函数的特点
$.when(send_action(action[0], arg2))
.done(function () {
//前一个ajax回调函数完毕之后判断队列长度
if (action.length > 1) {
//队列长度大于1,则弹出第一个,继续递归执行该队列
action.shift();
send(action, arg2);
}
}).fail(function (){
//队列中元素请求失败后的逻辑
//重试发送
//send(action, arg2);
//忽略错误进行下个
//if (action.length > 1) {
//队列长度大于1,则弹出第一个,继续递归执行该队列
// action.shift();
// send(action, arg2);
//}
});
}
//处理每个命令的ajax请求以及回调函数
function send_action(command, arg2) {
var dtd = $.Deferred();//定义deferred对象
$.post(
"url",
{
command: command,
arg2: arg2
}
).done(function (json) {
json = $.parseJSON(json);
//每次请求回调函数的处理逻辑
//
//
//
//逻辑结束
dtd.resolve();
}).fail(function (){
//ajax请求失败的逻辑
dtd.reject();
});
return dtd.promise();//返回Deferred对象的promise,防止在外部修改状态
}
工作中有时间碰到多个ajax请求,需要按照顺序进行数据请求且保证数据是按照请求的顺序有序返回。所以需要对请求进行包装处理。 jquery自带的case when方式仅能保证请求是按顺序发出的,但不能保证请求的数据按顺序返回。
具体处理方式如下:
1、创建一个存放ajax请求的数组,
2、创建一个执行ajax请求的函数,在函数内执行数组中第一个ajax函数,在请求返回后将该ajax函数删除,然后判断数组的长度,若数组长度大于零,表示还有请求没有完成,继续执行该ajax函数。实际上是利用递归原理来处理。
例:
var categorieList = [
{
categorieId: 1,
id: 11151, //测试用
type: "技术"
},{
categorieId: 2,
id: 11164, //测试用
type: "能力"
},{
categorieId: 3,
id: 11146, //测试用
type: "产品"
}
];
if( typeof(result.label) != "undefined" && !isBlank(result.label) ){
var ajaxes = []; //用于存储参数对象的队列
for(var i=0; i< categorieList.length; i++){
ajaxes.push({
categorieId: categorieList[i].categorieId,
type: categorieList[i].type,
result: result
});
}
创建执行ajax请求的函数:
var executeAjax = function(){
if(ajaxes.length < 1){
return;
}
var params = ajaxes[0];
$.ajax({
type: .....
success: function(response){
...
ajaxes.shift(); //删除队列中的第一个请求
if( ajaxes.length > 0){ //如果队列中还有请求,就接着递归执行executeAjax函数,直到队列为空
executeAjax();
}
}
});
};
executeAjax(); //执行函数请求。
本文详细介绍了Ajax的核心概念,包括其应用场景、优缺点、JSON数据转换、请求取消、请求发送方式以及与Fetch、Axios的对比。同时,探讨了Ajax的出现背景、跨域处理CORS机制,以及GET和POST方法的区别。此外,还讨论了如何通过Promise处理多个Ajax请求的顺序执行问题。
&spm=1001.2101.3001.5002&articleId=130541782&d=1&t=3&u=1b4a68326a8246949be04e81ebc70236)
25万+

被折叠的 条评论
为什么被折叠?



