JavaScript系列----AJAX机制详解以及跨域通信
1.Ajax
1.1.Ajax简介
Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的。所以,大多细节都是一笔带过。
Ajax的起源?
Ajax一词源于2005年 Jesse James Garrett发表的一篇题为"Ajax:A new Approach to Web Applications".他在这篇文 章中介绍了一种新技术,用他的话说,就是Ajax :Asynchronous JavaScript +XML的缩写。
Ajax是什么?
这种新技术的主要目的就是为了使前端网页能够向服务器请求额外的数据而不需要卸载页面。自从这种技术出现以后,微软率先引入XHR对象(ajax能够实现的核心对象),然后其他浏览器相继实现这种技术。总而言之,ajax就是一种能异步通信的技术。
1.2.Ajax的核心对象---XMLHttpRequest
因为IE5是最先引入这个XHR对象的,当时并没有事实上的标准。在IE中有三种不同的XHR对象版本:MSXML2.XMLHttp,MSXML2.XMLHttp.3.0和MSXML2.XMLHttp.6.0;
根据这三种版本号,在IE中创建一个XHR对象如下:
function createXHR() { //IE7之前的版本通过这种方式
var versions = [
'MSXML2.XMLHttp',
'MSXML2.XMLHttp.3.0',
'MSXML2.XMLHttp.6.0'
];
var xhr = null;
for (var item in versions) {
try {
xhr = new ActiveXObject(item); //若不存在该版本,可能会出错
if (xhr) break;
} catch (e) {
//一般对这种错误不做处理
}
}
return xhr;
}
在IE引入这个对象之后,其他浏览器厂商也相继跟随,这时候XHR对象成为事实上的标准!
跨浏览器创建XHR对象;
function createXHttpRequest() {
if (typeof XMLHttpRequest !== 'undefined') { //不要用 if(XMLHttpRequest){}这种形式,
return new XMLHttpRequest(); //如果是这种形式在找不到XMLHttpRequest函数的情况下,会报错。
} else if (typeof ActiveXObject !== 'undefined') {
return createXHR(); //用到刚才我们创建的函数
} else { throw new Error('不能创建XMLHttpRequest对象'); } }
1.2.XMLHttpRequest的用法
XMLHttpRequest对象的函数有6个:
open("method",url,boolean);
//该方法的三个参数,分别为----提交方式"get"或者"post"等
//&& url是相对于执行代码的当前页面的路径(使用绝对路径是允许的)&&是否异步
send();
//这个方法接收一个参数,这个参数是作为请求主体发送的数据,
//说明: 如果有参数,请使用post方式提交 使用方式如下,send("user="+username+"&pwd="+password);
//如果没有参数,为了兼容性考虑,必须在参数中传入null,即send(null);该方式使用get方式提交
abort(); //取消当前响应,关闭连接并且结束任何未决的网络活动。
//这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决 //的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。
getResponseHeader()
//返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任 //何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。
//该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyStat //e 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并 //返回,使用逗号和空格分隔开各个头部的值。
getAllResponseHeaders()
//把 HTTP 响应头部作为未解析的字符串返回。
//如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的
//头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 "\r\n" 隔开。
setRequestHeader()
//向一个打开但未发送的请求设置或添加一个 HTTP 请求。
XMLHttpRequest对象的属性有5个:
| 属性 | 描述 |
| responseText | 作为响应主题被返回的文本 |
| responseXML | 如果相响应的是text/html或者application/xml类型的话,这个属性将保存着响应的XML文档 |
| status | http的响应状态码 |
| statusText | http状态的说明 |
| readyState | XMLHttpRequest对象的状态位 0 1 2 3 4 分别表示5种状态 |
| timeout | 设置超时时间,单位是ms.目前只有IE8+支持---尚未标准化(不推荐使用) |
XMLHttpRequest对象的事件属性onReadyStateChange:-----所有浏览器兼容
该属性监听的是 XMLHttpRequest对象的readyState属性的变化:
readyState的变化分别对应如下状态:
:尚未初始化。未调用open()之前
:启动。调用open()之后,但是未调用send();
:发送。调用send()但是尚未得到响应。
:正在接收数据。刚接收到响应数据开始到接收完成之前。
: 完成。数据接收完成。
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status <== 300 || xhr.status == 304) {
alert(xhr.responseText);
//处理接收的数据
} else {
//请求失败,未得到响应数据
}
}
}; //补充说明:注册事件必须发生在send()以前
XMLHttpRequest对象的事件属性ontimeout -----仅限IE8+,不过最新的主流高版本浏览器也已经实现(不推荐使用)
xhr.timeout=1000;//一秒钟
xhr.ontimeout=functon(){
//处理代码
......
}
这种使用方式有个问题需要注意,就是在超时之后,在接收到数据后仍然会触发onreadystatechange事件,如果在处理onreadychange事件时访问xhr.status属性,会出错。所以我们在访问该属性时需要做一下try{}catch处理。但是,因为这个属性暂不兼容,所有我们就不重点讲了。
XMLHttpRequest对象的事件属性onload onerror onloadstar onbort onprogress:
-----非IE浏览器和IE 10+已实现
onload在IE8以上可以实现,大部分事件根据readySate变化均可以实现,以上事件只不过是方便使用而已。
onload和onprogress 这两种事件分别对应着readyState=4和readyState=3的情况,使用方式分别如下:
xhr.onload= function (event) {
//event只包含一个属性 event.target=xhr;使用方式只是在readyState=4时差不多..
}
xhr.onprogress=function(event){
//event除了包含event.target=xhr之外,还包含三种属性
//lengthComputale(进度信息是否可用),position(已接受字节数)和totalSize(总字节数).
}
补充:有些事件均可以根据readyState的状态进行模拟。只有有的浏览器进行了方便化处理而已。
3.单向跨域技术 ---CORS
今天我们这里讲的是客户端网页向不在同一个域的服务器请求数据..客户端在收到返回的数据时时,用回调函数处理数据。
即:
1. 客户端向域外服务器请求数据
2.服务器得到响应后向客户端发送数据。
3.客户端根据返回的数据执行回调函数.
我知道不同域下的iframe也可以进行通信,而且这也是一种跨域通信技术。但是,这种iframe页面之间的双向通信,我们在下一个专题里面讲解,今天主要讲的是单向通信。
3.1.CORS跨域请求的原理
在用xhr(XMLHttpRequest)对象或者xdr(XDomainRequest)对象,发送域外请求时,大概的实现原理如下图:
3.2.IE中CORS技术的实现
IE8引入了一个XDR类型,这个类型与XHR基本类似,但是其能实现安全可靠地跨域通信。
XHD的特点:
1.cookie不会随请求发送,也不会随响应返回。
2.只能设置请求头部中的Content-Type片段。
3.不能访问响应头部信息。
4.只是支持get和post请求。
XDR支持onload和onerror事件属性,且其使用方式和XHR基本一致,不过其open()只接收两个参数,默认是异步的。
var xdr = new XDomainRequest();
xdr.onload = function () {
//处理xdr.responseText
}
xdr.onerror = function () {
};
xdr.open('get', '绝对url');
xhr.send(null);
3.3.跨浏览器的CORS技术实现
在标准浏览器中XHR对象就已经可以自动实现跨域请求,但是XHR和XDR的不同之处:
1.XHR可以在设置 withCredentials =true时,浏览器会把cookie发送给服务器,服务器此时通过设置头部Access-Control-Allow-Credentials:true时来响应。如果,服务器不设置这个属性,则浏览器会触发onerror事件。
2.在回调函数中可以访问status和statusText属性,而且支持同步请求。
以下是实现跨域请求的代码:
function createCrosRequest(method, url) {
var xhr = new XMLHttpRequest(); //IE7+
if ('withCredentials' in xhr) { //IE8-IE9浏览器没有这个属性
xhr.open(method, url, true);
} else if (typeof XDomainRequest != 'undefined') {
xhr = new XDomainRequest(); //IE
xhr.open(method, url)
}
return xhr;
}
var request=CreateCrosRequest("get","url");
if(request){
request.onload=function(){
//处理request.responseText;
}
request.send(null);
}
4.单向跨域技术 ---JSONP技术
JSONP技术比较简单,其主要原理主要是利用script标签的特性。
script标签和image标签一样,它们都具有src属性,而且这个属性是可跨域的。
因为script标签返回的都是js代码,且该js代码会自动执行。所以,如果我们请求返回的数据也是类似一段js代码的形式,岂不是就可以实现在脚本加载完毕后自动执行。
如果我们的请求,返回的数据是 callback + '(' + json + ')'; 这种形式的数据, 那么在脚本加载完毕之后也就能自动执行callback()函数了.
4.1.客户端写法
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<button id="button">请求数据</button>
</body>
<script>
window.onload=function(){
var button=document.getElementById("ibutton");
function callback(data){
//处理data
}
button.onclick=function(){
var script=document.createElement("script");
script="http://www.sasd.com/json/?callbak=callback";
document.body.insertBefore(script,document.body.firstChild);//加载脚本 } }
</script>
</html>
1.客户端将回调函数名写入<Script>脚本的url参数中。
2.script加载的时候会发送跨域请求。
4.2.服务器端
1.通过url得到函数名,命名为callback
2.将请求的数据作为函数的参数格式转化json格式,命名为。
3.将返回结果拼接为 callback+"("+json+")"; --------返回的就是填充式的数据,这段数据在脚本中会自动执行。
4.返回数据.
4.3.JSONP技术的缺点
1.因为是通过url传参数,所以请求只能是get类型的。
2.<script>目前只有onload属性事件,onerror还没有统一化,如果加载脚本出错,客户端很难得到反馈。
3.所请求数据的站点必须是可信任的,如果返回的数据段中注入的有恶意的代码,危害较大,且难以发现。
JavaScript系列----AJAX机制详解以及跨域通信的更多相关文章
- 【从零开始搭建自己的.NET Core Api框架】(五)由浅入深详解CORS跨域机制并快速实现
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- javaScript系列:JSON详解
JSON详解 JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.XML也是一种数据交 ...
- 【转】solr+ajax智能拼音详解---solr跨域请求
本文转自:http://blog.csdn.net/wangzhaodong001/article/details/8529090 最近刚做完solr的ajax智能拼音.总结一下. 前端:jQuery ...
- 详解 CmProcess 跨进程通信的实现
CmProcess 是 Android 一个跨进程通信框架,整体代码比较简单,总共 20 多个类,能够很好的便于我们去了解跨进程实现的原理. 个人猜测 CmProcess 也是借鉴了 VirtualA ...
- 详解JS跨域问题
什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- 详解 CORS跨域的几种不同实现方式
CORS 定义 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequ ...
- 详解js跨域
什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. 对于端口和协议的不同,只能通过后台来解决.URL 说明 是否允许通信 http://www.a.com/a.js http ...
- 详解 JSONP跨域请求的实现
跨域问题是由于浏览器为了防止CSRF攻击(Cross-site request forgery跨站请求伪造),避免恶意攻击而带来的风险而采取的同源策略限制.当一个页面中使用XMLHTTPR ...
- jsonp详解及跨域请求
什么是JSONP? JSON是一种轻量级的数据传输格式语言,被广泛应用于当前Web应用中.JSON格式数据的编码和解析基本在所有主流语言中都被实现,所以现在大部分前后端分离的架构都以JSON格式进行数 ...
随机推荐
- 基于Quartz实现简单的定时发送邮件
一.什么是Quartz Quartz 是一个轻量级任务调度框架,只需要做些简单的配置就可以使用:它可以支持持久化的任务存储,即使是任务中断或服务重启后,仍可以继续运行.Quartz既可以做为独立的应用 ...
- HIT 1917 Peaceful Commission
这道题题意就是给你n对人,一对中编号为x,x+1,给你m对矛盾,表示这两个人不能同时选. 然后就是Two-Sat的模板题了,就是根据对称性,连边,加缩点,最后拓扑排序,求出一组可行解就可以了. #in ...
- 关于如何获取iframe中的元素
今天研究了一下iframe中元素的获取,发现有些地方还是有点坑的. 首先:如果使用纯前端手段,是没有办法获取非同源的iframe中的元素的,后面会提到后端手段 一.同源环境 1.首先在父页面获取ifr ...
- iptables使用实践
1.iptables 本质上是一组规则,报文从端口接收到之后,按照规则的顺序进行匹配,一旦匹配上则执行动作,后续就不再匹配. 2.为了体现出优先级,iptable分为4个表,5个链,如下: 优先级顺序 ...
- JSONP、图片Ping、XMLHttpRequest2.0等跨域资源请求(CORS)
跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...
- (转)Python爬虫利器一之Requests库的用法
官方文档 以下内容大多来自于官方文档,本文进行了一些修改和总结.要了解更多可以参考 官方文档 安装 利用 pip 安装 $ pip install requests 或者利用 easy_install ...
- Akka(28): Http:About Akka-Http
众所周知,Akka系统是基于Actor模式的分布式运算系统,非常适合构建大数据平台.所以,无可避免地会出现独立系统之间.与异类系统.与移动系统集成的需求.由于涉及到异类和移动系统,系统对接的方式必须在 ...
- C# 6.0 $"Hello {csdn}"
"hello $world"的格式化字符串是指把字符串中一个单词,以一个标示开头.可以代换为单词所指的变量. 这个在jq有,而C#string的格式只能用格式的字符占位符,格式的字 ...
- 进程池与线程池(concurrent.futures)
from concurrent.futures import ProcessPoolExecutor import os,time,random def task(n): print('%s is r ...
- shell script测试命令(test)
shell script测试命令(test) test命令 检查系统上面某些文件或者相关的属性 常用选项 test -e :检查该文件名是否存在 例:检查/dmtsai是否存在 [root@local ...
