AJAX及其跨域的主要解决方法

AJAX =
Asynchronous JavaScript andXML(异步的 JavaScript 和
XML)。通过在后台与服务器进行少量数据交换,使网页实现异步更新。要明白异步交互可以通过同步和异步的对比很容易明白:

同步交互,就是最常见的click-refresh模式,点一个连接或提交一个表单,然后就必须重载整个页面

异步交互,javascript根据返回的数据,不刷新页面而改变当前页面的显示,例如:新浪微博,百度地图。

   Ajax的异步交互从XMLHttpRequest这个对象开始,它允许通过javascript来执行HTTP请求,并且将会解析一个XML格式或者文本,json等格式的服务器响应,这个过程用户不用等待服务器的响应,用户可以继续进行其它操作。然后,服务器将数据返回,客服端对数据进行处理,可以不刷新页面使得用户得到了新数据。

  下面就来看XMLHTTPRequest的五步使用法,来实现异步交互:

  1.建立XMLHTTPRequest对象


1 if(window.XMLHttpRequest){
2 var xmlhttp=new XMLHttpRequest();
3 }else if(window.ActiveXObject){//ie6
4 var xmlhttp=new ActiveXObject();
5 }

 2.注册回调函数

1 xmlhttp.onreadystatechange=callback;

给xmlhttp对象注册onreadystatechange事件,并绑定回调函数。实际上每次readyState的值发生变化时,回调函数都会被调用,但是一般我们只关心状态4,表示响应已经完全接受。

  3.使用open方法设置和服务器端交互的基本信息 ,分别包含方法和交互方式,true为异步交互。

1 xmlhttp.open("GET","url?parmeters",true)

  4.设置发送的数据,开始和服务器端交互(由于get方法参数附加在url中,故不需要重复发送了)

1 xmlhttp.send(null)

对于post方法有些些微的不同:


1 //3.设置和服务器端交互的相应参数
2 xmlhttp.open("POST","url",true);
3 //设置post请求头信息
4 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
5 //4.设置服务器端发送的数据,启动和服务器端的交互
6 xmlhttp.send("name=" + userName);

  5.在回调函数中判断交互是否结束,响应是否正确,并根据需要获取服务器端返回的数据,更新页面内容


1 function callback(){
2 if(xmlhttp.readyState===4){
3 if(xmlhttp.status===200){
4 var message=xmlhttp.responseXML
5 }
6 }
7 }

补充点XMLHttpRequest对象的readyState 状态 ,总结如下:
(0)未初始化 
此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。
(1)载入
此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。
(2)载入完成
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。
(3)交互
此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。状态3表示正在解析数据。
(4)完成
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。

概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:创建-初始化请求-发送请求-接收数据-解析数据-完成

ajax的基本过程就是这样了。说到AJAX就必须面临两个问题:

  1. AJAX以何种格式来交换数据

  2. 跨域的需求如何来解决

这两个问题目前有不同的解决方法,比如数据可以用自定义的字符串或者XML来描述,跨域可以用服务器端代理来解决。但是到目前为止最优的方法还是用JSON来传递数据,用JSONP来跨域

json在此不再赘述。下文主要讲跨域方法

JSONP的产生:

  1. web页面上调用js文件则不受是否跨域的影响(不仅如此,我们还发现凡是拥有“src”这个属性的标签都拥有跨域的能力,标签的src属性并不
    被同源策略所约束,所以可以获取任何服务器上脚本并执行。比如<script><img><iframe>)

  2. 于是可以判断,当前阶段如果想通过纯web端跨域,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;

  3. 我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;

  4. 这样解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。

  5. 客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了。

  6. 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服
    务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

jsonp的核心就是在客服端创建包含回调函数的script,将<script>中的url定向到跨域的服务器脚本上。不同的请求创建不同的回调函数,服务器端根据这个回调函数动态的生成所需要的json数据,作为参数插入到回调函数中,客服端调用回调函数做出相应的动作。下面是一段客服端的脚本程序:


 1 <script type="text/javascript">
2 //得到航班信息查询结果后的回调函数
3 var flightHandler=function(data){
4 alert(‘你要查询的航班结果:票价‘+data.price+‘元,余票‘+data.tickets);
5 }
6 //提供jsonp服务的url地址(不管什么地址,最后生成的都是一段javascript代码)
7 var url="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
8 //创建script标签,并设置属性
9 var script = document.createElement(‘script‘);
10 script.src=url;
11 // 把script标签加入head,此时调用开始
12 document.getElementsByTagName(‘head‘)[0].appendChild(script);
13 </script>

我们看到调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,我的本地回调函
数叫做flightHandler,所以请把查询结果传入这个函数中。服务器端这个叫做flightResult.aspx的页面生成了一段这样的代码提
供给客服端来使用:

1 flightHandler({
2 "code": "CA1998",
3 "price": 1780,
4 "tickets": 5
5 });

我们看到,传递给flightHandler函数的是一个json,它描述了航班的基本信息。一个jsonp的执行全过程顺利完成!

AJAX及其跨域的主要解决方法,布布扣,bubuko.com

时间: 2024-12-14 18:40:41

AJAX及其跨域的主要解决方法的相关文章

ajax本地跨域请求以及解决方法

什么是跨域? ??我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景.所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源,只要没有同时满足这三个条件的请求即为跨域请求,跨域请求控制台一般会出现类似错误: XMLHttpRequest cannot load http://xxxxx.php. No 'Access-Control-Allow-Origin' header is present on the requested reso

jquery ajax跨域的完美解决方法(jsonp方式)

ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发 JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式.分别是JQuery的 jquery.ajax jsonp格式和jquer

jQuery ajax跨域请求的解决方法

在Ajax应用中,jQuery的Ajax请求是非常容易而且方便的,但是初学者经常会犯一个错误,那就是Ajax请求的url不是本地或者同一个服务器下面的URI,最后导致虽然请求200,但是不会返回任何数据,事实上简单来说请求同一个域名下的url或者说用不带http的绝对路径和相对路径请求是没有任何问题的,如果请求外部资源,那么这就称为跨域请求. 由于安全性的问题,浏览器默认不支持跨域调用,晚上也有很多方法,各有优缺点,但是有一个比较好的解决方法这也是jQuery1.2之后官方推荐的,那就是在客户端

SpringBoot+Ajax跨域安全问题及解决方法

〇.遇到跨域安全问题 在学习SpringBoot过程中,遇到了这样一个问题.当时用SpringBoot开发Rest服务接口,然后用Ajax请求获取数据,来实现前后端分离.但是在前端请求时,始终不能显示应该显示的数据.从浏览器的控制台报错来看(如下图),应该是遇到了跨域安全的问题. 一.为什么会出现跨域安全问题? 要解决这个问题,首先得知道为什么会出现这个问题.通过了解,出现跨域安全问题的原因一般是以下三个问题:浏览器收到了正确的返回数据但是做出了限制.发出去的请求是XMLHttpRequest请

AJAX实现跨域的三种方法

转 由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问. 比如说你的网站域名是aaa.com,想要通过AJAX请求bbb.com域名中的内容,浏览器就会认为是不安全的,所以拒绝访问. 会出现跨域问题的几种情况: 后台在百度上寻找解决方案解决了这个问题,一共总结出三种方案:代理.JSONP.XHR2(XMLHttpRequest Level 2). 第一种方法 代理:这种方式是通过后台(ASP.PHP.Ja

海康、大华等网络摄像头RTSP_Onvif网页无插件直播流媒体服务器EasyNVR鉴权出现跨域问题的解决方法

背景分析 随着平安城市.智慧城市.雪亮工程.智能交通等各项建设的持续开展,安防逐渐得到普及,面对如此广阔的市场,对安防企业来说不仅仅是机遇更多的是挑战.现今大多数摄像头一直没能摆脱人工监控的传统监控方式,由此导致了大量视频数据堆积占用存储资源.实时性差.检索困难等问题,海量摄像头带来的海量视频数据检索工作需要耗费大量警力. 为了解决这些问题,近年来,视频监控行业发展方向主要为:“高清化.网络化.智能化”.视频监控设备技术性极强,系统的创新升级同时也在引导市场需求的变化并创造了新的市场需求. Ea

WebApp开发:ajax请求跨域问题的解决

服务端:PHP 客户端:Andorid, HTML5, jQuery, ajax 现象:本想通过jQuery的ajax功能从服务器取回数据存到手机的缓存里,结果总是错误,后来想到可能是跨域问题,所以查了下jsonp的方案先把流程跑通,明天再完善看看有什么好的方案 服务端:http://www.code-style.com/test/a.php <?php //服务端返回JSON数据 $arr=array('name'=>'shujun.li'); $result=json_encode($ar

vue工程本地代码请求http发生跨域提示错误解决方法

这个可以使用代理进行跨域,这样看来跨域的方法就有几种了,对于iframe中的用postmassage,对于vue工程中的跨域则使用代理模式. 代理模式配置如下: 在config文件夹下找到index.js文件.找到module.exports下边的proxyTable属性,改成: // proxyTable: {},//代理才能跨域发送请求 proxyTable: devEnv.OPEN_PROXY === false ? {} : { '/proxyApi': { target: 'http:

vue-socket.io跨域问题的解决方法

报错信息: 1 Access to XMLHttpRequest at 'http://192.168.37.130:5050/socket.io/?EIO=3&transport=polling&t=N0oqNsW' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested