javascript基础-ajax
先看几种B/S交互的对比
B/S方式 | 阻塞页面 | 历史记录 | 协议 |
URL: get | —— | 自动记录 浏览器前进后退可访问 |
http/https |
form: get/post | 完全阻塞 | 自动记录 浏览器前进后退可访问 |
http/https |
ajax: get/post | 同步阻塞 异步不阻塞 |
HTML5才支持无刷新改变页面URL | http/https |
ajax异步请求时不阻塞页面,不影响用户的持续操作。这是ajax流行的原因。
XHR
XHR是AJAX的核心,写一个原生的ajax请求
var xhr = new XMLHttpRequest();//创建XHR实例 xhr.open('get','queNames.do', false);//启动请求。args[0]请求方式 args[1] URL args[2] async xhr.send(null);//发送请求 if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304){ //请求成功 cnosole.info(xhr.responseText);//拿到响应数据 }
xhr.abort()//中断请求
HTTP协议
ajax通过HTTP协议来完成交互,需要知道基本的HTTP协议知识
跨域
因为同源策略(ip,端口,域名)的限制,ajax不支持跨域访问,但项目中经常碰到跨域的需求
几种跨域的对比
跨域方式 | 请求方法 | 需改造后台 | 缺陷 |
jsonp | get | 是 | 无法携带凭证过去 |
img | get | 否 | 单向传递,不能获取响应 |
CORS | get/post | 是 | 完美! |
常用的这三种。其他更偏门的swf、父子iframe跨域这里不做讨论。CORS协议跨域,在IE8-不支持。标准浏览器均支持。
jsonp
原理
利用<script>标签。src里设置请求URL+callbackName。 callbackName即全局函数名。后台在输出流时调用此函数。
写法
前端(以jquery举例)
$.ajax({ url: "...", dataType: 'jsonp', jsonp:'callback', success: function(data) { } ... });
后台
PrintWriter writer = null; try { writer = response.getWriter(); String callback = request.getParameter("callback"); response.setContentType("application/javascript;charset=UTF-8"); writer.write(callback + "(" + data + ")");//调用客户端的全局函数,塞入数据data writer.flush(); return null; } catch (IOException e) { logger.error(e.toString()); }
img
var img = new Image(); img.onload = img.onerror = function() { alert("Done!"); }; img.src = "http://www.suning.com/a.do?name=value";
CORS
安全
ajax容易遭到CSRF攻击,两种方式来防范:1,敏感信息如密码用SSL连接 2,携带随机数
调试
打开chrome浏览器,按F12
Advanced Ajax 介绍
类型 | 描述 | 原理 | 适合场景 |
Comet(服务器推送) | 服务器向页面推送数据的技术,目的是保证数据的实时更新。Ajax是页面向服务器请求数据。Comet则是服务器向页面推送数据。两者相反。 | 短轮询:不断发请求 长轮询: 客户端请求-->服务器挂起,直到有数据响应-->客户端再请求 HTTP流: |
适合股票,互联网抢拍等需要实时同步的场景 |
SSE | 只读Comet | 服务器响应特定的MIME类型(text/event-stream)来保证数据传递给EventSource 自动断开重连。 通过事件open/close/error来控制连接 断开时,通过ID来保证数据顺序。 |
不需要传递数据给服务器的同步场景 |
Web Socket | WebSocket的目标是在一个持久连接上提供双向通信 | WebSocket协议
ws:// 依赖专门的服务器 |
Web QQ或聊天室 |
Comet
短轮询: 前端:setInterval($.ajax..,2000) 后台:—— 长轮询: 前端:$ajax-reponse-$ajax 请求..响应--请求..响应--... 后台: 数据未更新之前不关闭连接 HTTP流: 前端: xhr.onreadystatechange监听-->readyState==3时渲染数据 后端:开启线程监听,不关闭连接,有数据时输出,刷新缓存。
SSE
var source = new EventSource(url);//创建SSE source.onmessage = function(data){};//收到消息时 source.onerror = function(e){};//连接错误时 source.close();//关闭连接
Web Socket
var socket = new WebSocket('ws://localhost:8080'); // 创建一个Socket实例 socket.onopen = function(event) { //打开socket socket.send('suning!'); //发送消息给服务器 socket.onmessage = function(event) { //监听服务器消息的返回 console.info('message',event); }; socket.onclose = function(event) { //监听关闭 }; socket.close();// 关闭Socket }