1)、使用JavaScript获得浏览器内置的AJAX引擎(XMLHttpRequest对象)。
2)、通过AJAX引擎确定请求路径和请求参数。
3)、通知AJAX引擎发送请求。
AJAX引擎会在不刷新浏览器地址栏的情况下,发送请求。
1)、服务器获得请求参数。
2)、服务器处理请求参数(添加、查询等操作)
3)、服务器响应数据给浏览器。
AJAX引擎获得服务器响应的数据,通过执行javaScript的毁掉函数将数据传递给浏览器页面。
1)、通过设置给AJAX引擎的毁掉函数获得服务器响应的数据。
2)、使用JavaScript在指定的位置,显示响应数据,从而局部修改页面的数据,达到局部刷新目
同源策略:协议、域名、端口都相同,是一种安全策略,不同源的客户端脚本在没有明确授权的情况下,不能读取对方资源。
跨域问题是由于浏览器为了防止CSRF攻击,避免恶意攻击带来的风险而才去的同源策略限制。
跨域:当协议、域名、端口不同时,会出现跨域问题
在本地模拟跨域现象:
图1 图2
图二的127.0.0.1同样也指向localhost,但是与localhost不是一个域名。所以图2会出现跨域错误并且ajax执行error()方法:
如何解决ajax跨域
(1)JSONP方式
(2)跨域资源共享(CORS),即添加响应头
(3)代理请求方式
(1)JSONP
JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
jsonp只支持"GET"方式的传输类型
解决方法:
jsp:
servlet:
完整代码见github:https://github.com/xiaoan0705/Ajax
(2)只需在servlet中添加响应头
网上说要添加以上两句,但是我试了一下只要最上面的一句就可以了,get和post都能访问。即:
response.setHeader("Access-Control-Allow-Origin", "*");//*允许任何域
(3)代理的方式
服务器A的test01.html页面想访问服务器B的后台action,返回“test”字符串,此时就出现跨域请求,浏览器控制台会出现报错提示,由于跨域是浏览器的同源策略造成的,对于服务器后台不存在该问题,可以在服务器A中添加一个代理action,在该action中完成对服务器B中action数据的请求,然后在返回到test01.html页面。
手写jsonp代码
jsonp的作用主要是实现跨域的,同时可以实现跨域的标签有:<script>、<image>、<link>等
jsonp是通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL。这里的<script>和<image>元素类似,都有能力不受限地从其他域加载资源。
实现思路:
(1)先处理url,包括参数以及callback函数名
(2)创建一个新的script标签到页面上
(3)把处理好地回调函数挂到window对象上
(4)回调完再删掉script
<script> window.onload=function(){ //http://www.baidu.com?aa=11&callback=my_jsonp04349289664328899 var jsonp=function(url,params,callback){ //判断url有没有参数,没有在后面加“?”,有就在参数后面接“&” var queryString=url.indexOf('?')==-1?"?":"&"; //添加参数 params的形式为{"name":"123","age":"32"} for(item in params){ queryString += item+"="+params[item]+"&"; } //处理函数名 //Math.random()为0-1之间的小数,将 小数换成整数字符串 var random=Math.random().toString().replace('.',''); var cname='my_jsonp'+random; var cb='callback='+cname; queryString+=cb;//将callback参数拼接到url后面 var script=document.createElement('script'); script.src=url+queryString; document.body.appendChild(script); //把回调函数的名字赋给window window[cname]=function(params){ //这里执行回调的操作,用来处理参数 callback(params); //拿到了就删除这个script document.body.removeChild(script); }; } jsonp("http://www.baidu.com",{aa:11},function(){ console.log(params); }) } </script>