目录
1、readystatechange监听xhr对象的变化(readystate)
参考:
1、mdn XMLHttpRequest
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
2、jquery ajax
https://www.jquery123.com/jQuery.ajax/
3、同源策略
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
4、跨域资源共享
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
5、axios
http://www.axios-js.com/zh-cn/docs/
https://www.w3school.com.cn/ajax/index.asp
一、浏览器对服务器请求
- 地址栏 enter
- 特定元素的href(a、link);src(img、script,iframe)
- 表单提交
二、ajax
- 名称:Asynchronous Javascript And XML(异步的 JavaScript 和 XML)
- based on Google Suggest from 2005
-
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。
1、原生写法
// 1. 创建一个 XMLHttpRequest 类型的对象 —— 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 2. 打开与一个网址之间的连接 —— 相当于在地址栏输入访问地址;第三个参数默认true表示同步,false表示异步
xhr.open('POST', 'XXX',true);
// 3. 通过连接发送一次请求 —— 相当于回车或者点击访问发送请求
xhr.send(null);
// 4. 指定 xhr 状态变化事件处理函数 —— 相当于处理网页呈现后的操作
xhr.addEventListener("readystatechange",function(){
if (this.readyState !== 4) {
return ;
}
// 通过 xhr 的 responseText 获取到响应的响应体
console.log(this)
});
1、readystatechange监听xhr对象的变化(readystate)
readyState | 状态描述 | 说明 |
0 | UNSENT | 代理( XHR )被创建,但尚未调用open() 方法。 |
1 | OPENED | open()方法已经被调用,建立了连接。 |
2 | HEADERS_ _RECEIVED | send()方法已经被调用,并且已经可以获取状态行和响应头。 |
3 | LOADING | 响应体下载中,responseText 属性可能已经包含部分数据。 |
4 | DONE | 响应体下载完成,可以直接使用responseText 。 |
事件监听在open之前可以拿到4个状态(1234),之后只能拿到234
可以打印所有状态看一下,需要注意的是:
表面上看到的对象状态不一样(1,2,3,4),但是展开一样,都是最后一个4。
因为:
1、在 console.log 执行的时候,浏览器会对 log 的对象求一次值,打印出来是 Object ,可以继续展开的。
2、展开控制台中的 Object 的时候,chrome 又会对它求一次值,这一次是显示它的属性。
所以才会有前后打印的东西不一样的情况发生,因为对象引用的实体的值改变了。
如果把 console.log(aaaa) 改为 console.log(JSON.stringify(aaaa)), 这时就会输出
2、同步、异步
同步会等,时间长,不推荐!
主线程中同步的 XMLHttpRequest 已不推荐使用,因其对终端用户的用户体验存在负面影响。可访问 http://xhr.spec.whatwg.org/ 详细了解。
var xhr = new XMLHttpRequest();
console.time('xxx')
xhr.open('POST', 'XXX',false);
// 同步需要先注册再send
xhr.addEventListener("readystatechange",function(){
console.log(this)
});
xhr.send(null);
console.timeEnd('xxx')
异步体验好
小技巧:js计时
console.time('xxx')
console.timeEnd('xxx')
3、兼容ie5/6
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
三、jquery ajax
$.ajax({
url: './get',
type: 'get',
dataType: 'json',
data: { id: 1 },
beforeSend: function (xhr) {
console.log('before send')
},
success: function (data) {
console.log(data)
},
error: function (err) {
console.log(err)
},
complete: function () {
console.log('request completed')
}
})
快捷方法
// 快捷方法
// Example: 请求 test.php 页面, 但是忽略返回结果.
$.get("test.php");
Example: 请求 test.php 页面 并且发送url参数(虽然仍然忽视返回的结果)。
$.get("test.php", { name: "John", time: "2pm" } );
// Example: 传递数组形式data参数给服务器 (虽然仍然忽视返回的结果).
$.get("test.php", { 'choices[]': ["Jon", "Susan"]} );
// Example: Alert 从 test.php请求的数据结果 (HTML 或者 XML,取决于返回的结果).
$.get("test.php", function(data){
alert("Data Loaded: " + data);
});
使用一个HTTP GET请求从服务器加载JSON编码的数据。
$.getJSON("test.js", function(json) {
alert("JSON Data: " + json.users[3].name);
});
使用一个HTTP GET请求从服务器加载并执行一个 JavaScript 文件
$.getScript("ajax/test.js")
.done(function(script, textStatus) {
console.log( textStatus );
})
.fail(function(jqxhr, settings, exception) {
$( "div.log" ).text( "Triggered ajaxError handler." );
});
post
$.post('ajax/test.html', function(data) {
$('.result').html(data);
});
load: 从服务器载入数据并且将返回的 HTML 代码并插入至 匹配的元素 中。
$('#result').load('ajax/test.html', function() {
alert('Load was performed.');
});
// 部分加载
$('#result').load('ajax/test.html #container');
四、axios
http://www.axios-js.com/zh-cn/docs/
五、跨源(跨域)请求解决方案
同源:如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。
跨源:Cross-Origin,上面的三个有一个不同就是跨源
解决方案:jsonp、代理、CORS
1、jsonp
名称:JSON with padding(填充式 JSON 或参数式 JSON)
原理:就是动态创建< script>标签,然后利用< script>的src不受同源策略约束来跨域获取数据。
组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。
1. JSONP 需要服务端配合,服务端按照客户端的要求返回一段 JavaScript 调用客户端的函数
2. 只能发送 GET 请求
2、CORS
名称:Cross Origin Resource Share,跨域资源共享
原理:被请求的服务端响应的时候添加一个 Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。