作用:ajax用来与后台交互
字符串转对象
JSON.parse(json)
eval('(' + jsonstr + ')')
对象转字符串
JSON.stringify(json)
(1)原生xhr取消请求
var xhr = new XMLHttpRequest();
xhr.abort();
ajax常见面试题 - 掘金
XMLHttpRequest
JSON
AJAX
CORS
四个名词来开会
5种发起请求的方式,主流的、非主流的。
何种方式 | 请求方法 | |
---|---|---|
最常见的form 表单 |
默认GET ,多用POST ,只此两种 |
会刷新页面或者新开页面 |
a 标签 |
GET 请求 |
也会刷新页面或者新开页面 |
img 的src 属性 |
GET |
只能以图片的形式展现 |
link 标签 |
GET |
只能以CSS 、favicon 的形式展现 |
script 标签 |
GET |
只能以脚本的形式运行 |
可是
GET
POST
PUT
DELETE
方法浏览器和服务器交互模式 V1.0
在AJAX
未出现之前,浏览器想从服务器获得资源,注意是获取资源,会经过如下一个过程
既然AJAX
是一系列的技术的组合体,接下来认识一下其中的几位主角
XMLHttpRequest
对象是用来在浏览器和服务器之间传输数据的。
古代的操作的是:
XMLHttpRequest
实例化对象XML
格式的字符串,是字符串,是字符串,是字符串,也就是说响应的第四部分是字符串。什么是XML,可扩展标记语言。
XMLHttpRequest实例的详解
正如上面的前端代码片段写的一样,主要用到了open()
send()
方法, onreadystatechange
readyState
属性。
request.open(method, URL, async)方法。
GET POST DELETE PUT
等等,URL是用访问的路径,async是是否使用同步,默认true,开启异步,不需要做修改即可,所以实际中只写前两个参数request.send()方法。
readyState
属性。
描述请求的五个状态。
UNSENT
(未打开) open()方法未调用OPENED
(未发送) 只是open()方法调用了HEADERS_RECEIVED (已获取响应头)
send()方法调用了,响应头和响应状态已经返回了LOADING (正在下载响应体)
响应体下载中,responseText
已经获取了部分数据DONE (请求完成)
整个响应过程完毕了。 这个值是实际中用到的。responseText
属性是此次响应的文本内容。
onreadystatechange
属性。
readyState
属性的值发生改变,就会触发readyStateChange
事件。onReadyStateChange
属性,指定这个事件的回调函数,对不同状态进行不同处理。尤其是当状态变为4的时候,表示通信成功,这时回调函数就可以处理服务器传送回来的数据。即前面的代码片段的处理方式。其他的方法、属性、事件详见阮一峰博客、MDN文档
习惯用javaScript
的前端是不想和XML
打交道的,应该用一种符合js
风格的数据格式语言。
它是一门全新的数据交换语言,不是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" : "好久不见啊"
}
}
`)
AJAX
向非同源的地址发起请求,会报错。
上述请求响应都没有问题
然而对于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)。 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状态码 |
不需要 |
需要 |
被调用次数 |
一次 |
多次 |
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方法后,不会在此处一直等待服务器执行的结果,而是继续往后执行后面的代码。
xhr.readyState // 获取Ajax状态码
0 - (未初始化)还没有调用 send()方法
1 - (载入)已调用 send()方法,正在发送请求
常用的post,get,delete。不常用copy、head、link等等。
(1)get通过url传递参数
(2)post设置请求头 规定请求数据类型
(1)post比get安全 ,(因为post参数在请求体中。get参数在url上面)
(2)get传输速度比post快 根据传参决定的。(post通过请求体传参,后台通过数据流接收。速度稍微慢一些。而get通过url传参可以直接获取)
(3)post传输文件大理论没有限制, get传输文件小大概7-8k ie4k左右;
(4)get获取数据 post上传数据,(上传的数据比较多 而且上传数据都是重要数据。所以不论在安全性还是数据量级 post是最好的选择)。
参考回答:
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命令,因为数量不定,所以采用递归
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请求顺序执行 - 一路前行 - ITeye博客