AJAX= JS+XML+JSON+HTTP通信,本质就是在HTTP协议的基础上以异步的方式进行通信。
- 比如说我有一个学生数据:
- name = "孙悟空" ; age = 18 ; gender = "男" ;
- 用 XML 表示:
- <student>
- <name>孙悟空name>
- <age>18age>
- <gender>男gender>
- student>
用 JSON 表示: {"name":"孙悟空","age":18,"gender":"男"}
ajax也叫做无刷新技术比如地图、局部加载
①优点:
1.可以无需刷新页面而与服务器端进行通信。
2.可以充分利用客户端闲置的处理能力,减轻服务器和网络传输的负担。(比如划到下面才展示下面的数据,某些模块点击才会显示出 dialog 界面,显示相应的数据。)
3.使得web中界面与应用相分离 也可以说是数据与呈现相分离
②缺点:
1.没有浏览历史,不能回退 ,AJAX干掉了Back和History功能,即对浏览器机制的破坏。
2.AJAX安全问题,存在跨域问题,不能跨页面访问
3.SEO不太友好,界面数据都是通过 ajax请求动态获取得到的
ajax模块在处理网络请求的时候包括以下四个步骤
①通过XMLHttpRequest类创建xhr对象
②为xhr对象添加属性与回调方法
③令xhr对象执行open()方法,指明请求被发往某处
// 规定请求的类型、URL 以及是否异步处理请求。 xhr.open('GET',url,true);
④令xhr对象执行send()方法,发出请求。
补充:Ajax可以发出同步请求,也可以发出异步请求。但大多数情况下指的是异步请求,因为同步的Ajax请求对浏览器会产生‘阻塞效应。
- /**
- *需求: 点击 button 按钮发送 GET请求,将服务端返回的响应体结果返回在 div 中,页面不刷新
- */
- // 获取 button 元素
- const btn = document.getElementsByTagName('button')[0];
- const result = document.getElementById('result');
- btn.onclick = function() {
- // 1. 创建对象
- const xhr = new XMLHttpRequest();
- // 2. 初始化 设置请求方法和 url /server 是设置路径
- // 给 url 传递参数 用?分割加参数与值 进行传参,参数之间用&分割
- xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200&c=300');
- // 3. 发送
- xhr.send();
- // 4. 事件绑定,处理服务器返回的结果
- // on when··· 当····时
- // readystate 是 xhr 对象中的属性,表示状态
- // 其状态值分别为 0(未初始化) 1(open方法已调用完毕) 2(表示send方法已调用完毕) 3(服务端已返回部分结果) 4(服务端返回全部结果)
- // change 改变
- xhr.onreadystatechange = function () {
- // 判断 (服务端返回了全部结果)
- if(xhr.readyState === 4){
- // 判断响应状态码 200 404 403 401 500
- // 2xx 都表示成功
- if(xhr.status >= 200 && xhr.status < 300){
- /**
- // 处理结果 行 头 空行 体
- // 1.响应行
- console.log(xhr.status); // 状态码
- console.log(xhr.statusText); // 状态字符串
- console.log(xhr.getAllResponseHeaders()); // 所有的响应头
- console.log(xhr.response); // 响应体
- */
-
- //设置result文本
- result.innerHTML = xhr.response;
- }else {
-
- }
- }
- }
- }
-
- /**
- * 当鼠标放在 div 上面时,发送POST请求,将响应体结果在div当中呈现
- */
- // 获取元素对象
- const result = document.getElementById('result');
- //绑定事件
- result.addEventListener('mouseover',function () {
- // 1. 创建对象
- const xhr = new XMLHttpRequest();
- // 2. 初始化 设置类型与 url
- xhr.open('POST','http://127.0.0.1:8000/server');
-
- //设置请求头
- // 第一个参数: 头名 设置请求体内容的类型
- // 第二个参数:头值 参数查询字符串的类型 (写法固定)
- // 加预定义的响应头
- xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
- // 如果要设置自定义的响应头,需要后端人员在.js文件中设置
- xhr.setRequestHeader('name','atguigu');
-
-
- // 3. 发送
- // post请求 参数的设置是在 send()方法中
- // xhr.send('a=100&b=200&c=300');
- xhr.send('a:100&b:200&c:300');
-
- // 4. 事件绑定
- xhr.onreadystatechange = function () {
- // 判断
- if(xhr.readyState === 4){
- if(xhr.status >= 200 && xhr.status < 300){
- // 处理服务器端返回的结果
- result.innerHTML = xhr.response;
- }
- }
- }
- })
常用的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是最好的选择)
同源策略限制 不同源会造成跨域。以下任意一种情况不同,都是不同源。
http://www.baidu.com/8080/index.html
| http:// | 协议不同 |
|---|---|
| www | 子域名不同 |
| baidu.com | 主域名不同 |
| 8080 | 端口号不同 |
| www.baidu.com | ip地址和网址不同 |
动态创建一个script标签。利用script标签的src属性不受同源策略限制。因为所有的src属性和href属性都不受同源策略限制。可以请求第三方服务器数据内容。
- //去创建一个script标签
- var script = document.createElement("script");
-
- //script的src属性设置接口地址 并带一个callback回调函数名称
- script.src = "http://127.0.0.1:8888/index.php?callback=jsonpCallback";
-
- //插入到页面
- document.head.appendChild(script);
-
- //必须通过定义函数名去接收后台返回数据
- function jsonpCallback(data){
- //注意 jsonp返回的数据是json对象可以直接使用
- //ajax 取得数据是json字符串需要转换成json对象才可以使用
- console.log(data)
- }
服务器端设置Access-Control-Allow-OriginHTTP响应头之后,浏览器将会允许跨域请求
浏览器需要支持HTML5,可以支持POST,PUT等方法兼容ie9以上
- 需要后台设置
- Access-Control-Allow-Origin: * //允许所有域名访问,或者
- Access-Control-Allow-Origin: http://a.com //只允许所有域名访问
相同主域名不同子域名下的页面,可以设置document.domain让它们同域
此方案仅适用于主域相同,子域不同的前端通信跨域场景。如下图所示,两个不符合同源策略的页面http://a.qq.com/a.html和http://b.qq.com/b.html,其主域相同为qq.com。a.html嵌套b.html,再都通过js设置document.domain为主域qq.com,则两个页面满足了同源策略,从而实现了跨域通信。
document.domain+iframe方案代码示例:
1、在http://a.qq.com/a.html和http:/b.qq.com/b.html两个文件中都加上document.domain = "qq.com";
2、通过a.html文件创建一个iframe,去控制iframe的window,从而进行交互。
- <iframe id="iframe" src="http://b.qq.com/b.html">iframe>
- <script>
- document.domain = "qq.com";
- var windowB = document.getElementById("iframe").contentWindow;
- alert("B页面的user变量:" + windowB.user);
- script>
- <script>
- document.domain = "qq.com";
- var user = "saramliu";
- script>
document.domain+iframe方案优点:
document.domain+iframe方案缺点:
关于contentWindow和contentDocument区分
定义和用法
contentDocument 属性能够以 HTML 对象来返回 iframe 中的文档,可以通过所有标准的 DOM 方法来处理被返回的对象。
语法:
frameObject.contentWindow,或者 iframeObject.contentWindow(不是jquery对象)
用iframe嵌套页面时,如果父页面要获取子页面里面的内容,可以使用contentWindow或者contentDocument,其区别如下:
1、contentWindow 这是个只读属性,返回指定的iframe的窗口对象。它虽然不是标准的一部分,但各个主流浏览器都支持。
2、contentDocument Firefox 支持,IE6,IE7都不支持,IE8开始支持,需要如此访问 document.frames['J_mainframe'].document。
请求已经被服务器接收,继续处理
200 (成功) 服务器已成功处理了请求。 通常正常访问返回。
3xx (重定向) 表示要完成请求,需要进一步操作才能完成这一请求。
- 301(moved permannently) 表示永久重定向,表示请求的资源分配了新的url,以后使用新的url
-
- 302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URl
-
- 304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
-
- 305 Use Proxy 使用代理。所请求的资源必须通过代理访问
-
- 306 Unused 已经被废弃的HTTP状态码
-
- 307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
4xx 客户端错误,请求包含语法错误或无法完成请求
- 常用 400 (错误请求 Bad Request) 客户端请求的语法错误,服务器无法理解
-
- 常用 403 (禁止 Forbidden) 服务器理解请求客户端的请求,但是拒绝执行此请求
-
- 常用 404 (未找到 Not Found) 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
-
-
- 401 未授权 Unauthorized 请求要求用户的身份认证
-
- 405 Method Not Allowed 客户端请求中的方法被禁止
-
- 407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
-
- 408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
-
- 410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
5xx 服务器错误,服务器在处理请求的过程中发生了错误
- 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
-
- 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
-
- 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
-
- 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
-
- 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
-
- 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本,无法完成处理。
- $.ajax({
- url: "请求路径",
- type: "post",
- contentType: "application/json; charset=utf-8",
- data: JSON.stringify({
- id:'666',
- name:'莎莎酱'
- }), //将json对象转为json字符串
- dataType: "json", //表示接受的数据为json类型
- success: function (data) {
- // 请求成功后执行的代码
- if (data.success) {
-
- } else {
-
- }
- },
- error: function(){
-
- }
要求为String类型的参数,(默认为当前页地址)发送请求的地址。
就是在此发送需求到对应的后台去处理,后台根据这个url来区别不同的请求。
要求为String类型的参数,请求方式(post或get)默认为get。
注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
浏览器把各表单字段元素及其数据作为HTTP消息的实体内容发送给Web服务器,数据量要比使用GET方式传送的数据量大的多,安全。
get方式可传送简单数据,有大小限制,数据追加到url中发送(http的header传送),url可以被客户端缓存,从浏览器的历史记录中得到客户数据,不安全。
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。
如果需要发送同步请求,请将此选项设置为false。
注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。
发送到服务器的数据,要求为Object或String类型的参数。
如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。
防止这种自动转换,可以查看processData选项。
对象必须为key/value格式。如果是数组,JQuery将自动为不同值对应同一个名称。
- // 对象必须为key/value格式。例如:
- {
- foo1:"bar1",
- foo2:"bar2"
- }
- =>&foo1=bar1&foo2=bar2
-
- // 如果是数组,JQuery将自动为不同值对应同一个名称。例如:
- {
- foo:["bar1","bar2"]
- }
- => &foo=bar1&foo=bar2
要求为String类型的参数,预期服务器返回的数据类型。
如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。
- 常用类型:
- xml:返回XML文档,可用JQuery处理。
- html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
- json:返回JSON数据。如果指定为json类型,则会把获取到的数据作为一个JavaScript对象来解析,并且把构建好的对象作为结果返回。
- text:返回纯文本字符串。
要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。
- 1 function(data, textStatus){
- 2 //data就是后台处理之后,返回的一个javascript对象,里面包含前台需要的各种信息,需要什么塞什么,data可能是xmlDoc、jsonObj、html、text等等
- 3 this; //调用本次ajax请求时传递的options参数
- 4 }
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。
- 1 function(XMLHttpRequest, textStatus, errorThrown){
- 2 //通常情况下textStatus和errorThrown只有其中一个包含信息
- 3 this; //调用本次ajax请求时传递的options参数
- 4 }
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
multipart/form-data:有时候也会这个,上传下载可能会用到。
contentType: “application/json; charset=utf-8” 这个也可能常会用到。
要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
说完了进程和线程,现在再来聊一下同步和异步
大家都知道js是单线程机制的,它分为两种工作模式,同步模式和异步模式。
同步:就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。简单点来说,同步就是必须一件一件事做,等前一件做完了才能做下一件事。
异步:与异步相对,它在发出一个功能调用是,在没得到结果前,可以继续去进行后续操作,等调用完成后在通知调用者。通俗点讲就是这件事正在做,没做完,但是你可以去做下一件事,等这件事做完了,再通知你。