JavaScript AJAX
什么AJAX?
AJAX= Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
什么异步和同步?
同步: 按顺序,按步骤执行
异步: 同时发生
进程是什么?
一个程序从开始执行,到执行结束的过程,称之为一次进程
操作系统的多进程 (优先级)
线程是什么?
一个程序内部的执行分支。
多线程的目的, 为了提高效率。
所有线程共享一块内存
线程的优先级和死锁?
JS不支持多线程开发
function m1(){
}
function m2(){
}
多线程: m1和m2同时发生
var onlinecount = 100;
多线程处理同一资源时,会造成资源的不稳定,也就通常所说的“线程安全问题”
解决方案:线程锁
线程锁带来的问题:死锁
JS中的线程
异步操作: 回调函数
setTimeout(function(){
},2000)
obj.onclick = function(){
}
ajax的第一个应用
谷歌的搜索下拉提示
局部刷新的好处及应用场景
用户名的检测、 视频的点赞、弹幕、评论、加载更多
get请求和post请求的区别?
GET 还是 POST? 与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。
然后在 send() 方法中规定您希望发送的数据:
xmlhttp.open("POST","/try/ajax/demo_post2.php",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Henry&lname=Ford");
ajax的编写步骤
//第一 创建request对象 var xhr = ActiveXObject?new ActiveXObject("Msxml2.XMLHTTP"):new XMLHttpRequest() ;//IE || 常规浏览器 //第二 将这个对象设置为开启状态 /* 1请求方式 2请求地址 3是否异步 */ xhr.open("get", url, true); //第三 //请求完成后的动作 if(!!xhr.onload){ xhr.onload = function(){ alert(xhr.responseText); } } else { xhr.onreadystatechange = function(){//xhr.readyState 取值范围 0 1 2 3 4 if(xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } } } //第四 发送 xhr.send();
request对象的兼容
new ActiveXObject("Msxml2.XMLHTTP")
//老版本的
Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
var req = ActiveXObject?new ActiveXObject("Msxml2.XMLHTTP"):new XMLHttpRequest() ;
注:
var xhr = ActiveXObject?new ActiveXObject("Msxml2.XMLHTTP"):new XMLHttpRequest() ;
返回值只有两种,一种是xml另一种是text
数据的远程传输,异构系统通信(webservice)
在早期的网络通信当中,我们都是统一采用xml这种格式来发送和接收数据。
这对于异构系统来讲,是比较方便的。
当一个JS程序向一个JAVA服务器请求数据的时候,例如请求学生张三的个人信息。
JAVA返回的数据格式为XML。例如:
<student id="9527">
<name>张三</name>
<age>18</age>
<school>清华</school>
<lv desc="这个属性表示等级">100</lv>
</student>
{
"id": 9527,
"name": "张三",
"age": 18,
"school": "清华",
"lv": {
desc : "xxxx",
value : 100
}
}
JS天生具备DOM操作的能力,因此解析这种文本当然不在话下了
但是,XML格式相对而言,编写比较繁琐,数据文件较大,解析速度不快
后来,JSON格式就开始流行起来。
JSON格式有着更巨大的天然优势:
1、它编写简单,容易
2、它结构清晰,易阅读
3、数据占用空间较小,在网络传输时速度更快
4、更重要的是,它是JS原生表示对象的方法,可以轻易的把json字符串转换为JS对象。
因此,后来的网络通信,json格式就变得越来越流行了。
关键词:xml数据, soap协议, webservice技术
AJAX的同源策略
页面发起的请求,必须和页面的来源是一致的
跟cookie 的同源策略一致,都是为了保证安全。
当请求的域名地址跟当前网页的域名地址不一样的时候,浏览器即认为是跨域请求
例如你打开的网页地址是: http://10.15.26.133:8080/test.html
该网页发起的ajax请求地址: http://10.15.26.133:8888/test.html
尽管请求地址是同一台计算机。IP地址相同,但端口不同
蓝色部分(协议,域名,端口号),被认为是域名部分,只要这部分不一致,就是跨域
AJAX 跨域解决方案:
预备知识:
浏览器的同源策略 https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
1、在服务器返回头信息中加入Access-Control-Allow-Origin
2、让服务端代理解析跨域的地址,再将解析的结果返回给当前 “域”的页面,因为服务端没有跨域的问题
3、通过修改document.domain来跨子域
将子域和主域的document.domain设为同一个主域.前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域
主域相同的使用document.domain
使用window.name来进行跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的
使用HTML5中新引进的window.postMessage方法来跨域传送数据
还有flash、在服务器上设置代理页面等跨域方式。个人认为window.name的方法既不复杂,也能兼容到几乎所有浏览器,这真是极好的一种跨域方法。
将子域和主域的document.domain设为同一个主域.前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域
主域相同的使用document.domain
使用window.name来进行跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的
使用HTML5中新引进的window.postMessage方法来跨域传送数据
还有flash、在服务器上设置代理页面等跨域方式。个人认为window.name的方法既不复杂,也能兼容到几乎所有浏览器,这真是极好的一种跨域方法。
4、JSONP
全称叫做 Json width Padding
原理是在页面上动态的创建script标签,通过标签的src属性向服务器发起请求
此时服务器会动态的生成JS文件,并携带数据一并返回
注:因为通过JavaScript标签引入,而javascript标签只能做get请求,因此jsonp方法只能做get请求
例如百度的搜索提示接口:
请求地址为 http://suggestion.baidu.com/?cb=test&wd=hello
( 其中cb是返回的回调函数名)
返回的JS文本如下:
test({q:"hello",p:false,s:["hello kitty","hello 树先生","hello kitty藏尸案","hello world","hellobike","hello
tv","hello venus","hello女神","hellotalk","hellokitty主题乐园"]});
这样一来,如果本地已经事先定义好了函数test,就可以顺利得到数据了。
由于script标签请求没有域名限制,加上加载执行文件是异步的,因此达到了异步并且跨域的效果。所以JSONP是使用最广泛的AJAX跨域方案。
又如:服务器代理 获取 天气预报
http://www.weather.com.cn/data/sk/101010100.html注:101010100 代表地区编码
"北京","上海","天津","重庆"
"101010100","101020100","101030100","101040100"
XMLHttpRequest Level2 新标准 & 异步文件上传
var xhr = new XMLHttpRequest(); xhr.onload = 请求完成时,触发该函数 xhr.timeout = 设定有效时间 xhr.ontimeout = 当超时以后,触发该函数 xhr.onprogress = function()..... 返回数据的进度 xhr.upload.onprogress = function(event){ //上传文件的进度 if(event.lengthComputable){ var percent = event.loaded / event.total; } } lengthComputable 表示进度是否可计算 loaded 表示已经完成多少字节 total 表示总共多少字节5、socket解决方案
socket请求无跨域问题
瀑布流
瀑布流
window.onresize = function(){ if(document.body.scrollTop + window.innerHeight == document.body.offsetHeight){ loadImg(); } }
ajax 中 contenttype withcredentials 的坑
get请求中出现特殊字符
如:空格、# 等,导致请求时参数传递错误,例如
person/query?name=fan#qiang
传递的参数最终会变为
name = fan
因为“#”这个字符对URI来说,它的作用是指向一个锚点(任意一个元素的ID),因此稳妥的办法是进行转译后再传输
"person/query?name="+ encodeURIComponent(fan#qiang)
注:jquery源码中就有对ajax请求时key及value都进行转译