《ajax跨域问题.docx》由会员分享,可在线阅读,更多相关《ajax跨域问题.docx(32页珍藏版)》请在三一办公上搜索。
1、ajax跨域问题那么知道什么是Jsonp和pjax吗? 答案: Jsonp:(JSON with Padding)是一种跨域请求方式。主要原理是利用了script 标签可以跨域请求的特点,由其 src 属性发送请求到服务器,服务器返回 js 代码,网页端接受响应,然后就直接执行了,这和通过 script 标签引用外部文件的原理是一样的。JSONP由两部分组成:回调函数和数据,回调函数一般是由网页端控制,作为参数发往服务器端,服务器端把该函数和数据拼成字符串返回。 pjax:pjax是一种基于ajax+history.pushState的新技术,该技术可以无刷新改变页面的内容,并且可以改变页面的
2、URL。pjax是ajax+pushState的封装,同时支持本地存储、动画等多种功能。目前支持jquery、qwrap、kissy等多种版本。 jQuery Ajax 简单的实现跨域请求 html 代码清单: script type=text/javascript src= $(function $.ajax( type:get, url : dataType : jsonp, jsonp:jsoncallback, success : function(data) alert(用户名:+ data.user + 密码:+ data.pass); , error : function ale
3、rt(fail); ); ) 服务端 validate.php 代码清单: $_GETloginuser, pass = $_GETloginpass, name = response ); echo $_GETjsoncallback . (.json_encode($arr).); 效果图: AJAX 跨域请求 - JSONP获取JSON数据 博客分类: Javascript /Jquery / Bootstrap / Web Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点的关键技术。Ajax 允许在不干扰 Web 应用程序的显示
4、和行为的情况下在后台进行数据检索。使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。 不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数 据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办? 理解同源策略限制 同源策略阻止从一个
5、域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。 克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限
6、制。 克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。 1、什么是JSONP? 要了解JSONP,不得不提一下JSON,那么什么是JSON ? JSON is a subset of the object literal notation of Java
7、Script. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss. JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。 2、JSONP有什么用? 由于同源策略的限制,XmlHttpRequest只允许请求当前源的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的
8、数据请求。 3、如何使用JSONP? 下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数。 HTML代码 : Html代码 1. 2. 3. function jsonpCallback(result) 4. /alert(result); 5. for(var i in result) 6. alert(i+:+resulti);/循环输出a:1,b:2,etc. 7. 8. 9. var JSONP=document.createElement(script); 10. JS
9、ONP.type=text/javascript; 11. JSONP.src= 12. document.getElementsByTagName(head)0.appendChild(JSONP); 13. 或者 Html代码 1. 2. 3. function jsonpCallback(result) 4. alert(result.a); 5. alert(result.b); 6. alert(result.c); 7. for(var i in result) 8. alert(i+:+resulti);/循环输出a:1,b:2,etc. 9. 10. 11. 12. scrip
10、t type=text/javascript src= JavaScript的链接,必须在function的下面。 服务端PHP代码 : Php代码 1. 1,b=2,c=3,d=4,e=5); 5. $result=json_encode($arr); 6. /echo $_GETcallback.(Hello,World!); 7. /echo $_GETcallback.($result); 8. /动态执行回调函数 9. $callback=$_GETcallback; 10. echo $callback.($result); 如果将上述JS客户端代码用jQuery的方法来实现,也非
11、常简单。 $.getJSON $.ajax $.get 客户端JS代码在jQuery中的实现方式1: Js代码 1. 2. 3. $.getJSON( 4. function(result) 5. for(var i in result) 6. alert(i+:+resulti);/循环输出a:1,b:2,etc. 7. 8. ); 9. 客户端JS代码在jQuery中的实现方式2: Js代码 1. 2. 3. $.ajax( 4. url: 5. dataType:jsonp, 6. data:, 7. jsonp:callback, 8. success:function(result)
12、 9. for(var i in result) 10. alert(i+:+resulti);/循环输出a:1,b:2,etc. 11. 12. , 13. timeout:3000 14. ); 15. 客户端JS代码在jQuery中的实现方式3: Js代码 1. 2. 3. $.get( name: encodeURIComponent(tester), function (json) for(var i in json) alert(i+:+jsoni); , jsonp); 4. 其中 jsonCallback 是客户端注册的,获取 跨域服务器 上的json数据 后,回调的函数。 这
13、个 url 是跨域服务 器取 json 数据的接口,参数为回调函数的名字,返回的格式为 Js代码 1. jsonpCallback(msg:this is json data) Jsonp原理: 首先在客户端注册一个callback, 然后把callback的名字传给服务器。 此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。 客户端浏览器,解析script标签
14、,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里. 使用JSON的优点在于: 比XML轻了很多,没有那么多冗余的东西。 JSON也是具有很好的可读性的,但是通常返回的都是压缩过后的。不像XML这样的浏览器可以直接显示,浏览器对于JSON的格式化的显示就需要借助一些插件了。 在JavaScript中处理JSON很简单。 其他语言例如PHP对于JSON的支持也不错。 JSON也有一些劣势: JSON在服务端语言的支持不像XML那么广泛,不过JSON.org上提供很多语言的库。 如果你使用eval来解析的话,会容易出现安全问题。 尽管
15、如此,JSON的优点还是很明显的。他是Ajax数据交互的很理想的数据格式。 主要提示: JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。 第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。 JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSO
16、N 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要 jquery中ajax处理跨域的三大方式 一、处理跨域的方式: 1.代理 2.XHR2 HTML5中提供的XMLHTTPREQUEST Level2已经实现了跨域访问。但ie10以下不支持 只需要在服务端填上响应头: header(Access-Control-Allow-Origin:*); /*星号表示所有的域都可以接受,*/ header(Access-Control-Allow-Methods:GET,POST); 3.jsonP 原理: aj
17、ax本身是不可以跨域的, 通过产生一个script标签来实现跨域。因为script标签的src属性是没有跨域的限制的。 其实设置了dataType: jsonp后,$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议。JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。 ajax的跨域写法: : 比如 /*当前网址是localhost:3000*/ js代码 $.ajax( type:get, url:http:/localhost:3000/show
18、All,/*url写异域的请求地址*/ dataType:jsonp,/*加上datatype*/ jsonpCallback:cb,/*设置一个回调函数,名字随便取,和下面的函数里的名字相同就行*/ success:function 。 ); /*而在异域服务器上,*/ app.js app.get(/showAll,students.showAll);/*这和不跨域的写法相同*/ /*在异域服务器的showAll函数里,*/ var db = require(./database); exports.showAll = function(req,res) /*设置响应头允许ajax跨域访问
19、*/ res.setHeader(Access-Control-Allow-Origin,*); /*星号表示所有的异域请求都可以接受,*/ res.setHeader(Access-Control-Allow-Methods,GET,POST); var con = db.getCon; con.query(select * from t_students,function(error,rows) if(error) console.log(数据库出错:+error); else /*注意这里,返回的就是jsonP的回调函数名+数据了*/ res.send(cb(+JSON.stringif
20、y(r)+); ); 二、解决ajax跨域访问、 JQuery 的跨域方法 JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。 下面开始贴出方法。 /跨域 $.getJSON( /要求远程请求页面的数据格式为: ?(json_data) /例如: /?(_name:湖南省,_regionId:134,_name:北京市,_regionId:143) alert(json0._name); )
21、; $.getJSON( /要求远程请求页面的数据格式为: ?(json_data) /例如: /?(_name:湖南省,_regionId:134,_name:北京市,_regionId:143) alert(json0._name); ); 注意,getregion.aspx中,在输出JSON数据时,一定要用Request.QueryStringjsoncallback,将获取的内容放到返回JSON数据的前面,假设实际获取的值为42342348,那么返回的值就是 42342348(_name:湖南省,_regionId:134,_name:北京市,_regionId:143) 因为getJ
22、SON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。 下面一个是跨域执行的真实例子: /跨域 $.getJSON( id: 0, action: jobcategoryjson , function(json) alert(json0.pid); alert(json0.items0._name); ); /跨域 $.getJSON( id: 0, action: jobcategoryjson , function(json) alert(json0.pid); alert(json0.items0._name); ); jQuery跨域原理: 浏览器会进行同源检查,
23、这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的标记;我们经常使用的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器; 看下面的例子: script type=text/javascript src= 响应值:parseResponse(Name: Cheeso, Rank: 7) script type=text/javascript
24、src= 响应值:parseResponse(Name: Cheeso, Rank: 7) 这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢? 貌似并没有标记的出现!?OKay,翻看源码来看: 页面调用的是getJSON: getJSON: function( url, data, callback ) return jQuery.get(url, data, callback, json); , 继续跟进 get: function( url, data
25、, callback, type ) / shift arguments if data argument was omited if ( jQuery.isFunction( data ) ) type = type | callback; callback = data; data = null; return jQuery.ajax( type: GET, url: url, data: data, success: callback, dataType: type ); 跟进jQuery.ajax,下面是ajax方法的代码片段: / Build temporary JSONP func
26、tion if ( s.dataType = json & (s.data & jsre.test(s.data) | jsre.test(s.url) ) jsonp = s.jsonpCallback | (jsonp + jsc+); / Replace the =? sequence both in the query string and the data if ( s.data ) s.data = (s.data + ).replace(jsre, = + jsonp + $1); s.url = s.url.replace(jsre, = + jsonp + $1); / We
27、 need to make sure / that a JSONP style response is executed properly s.dataType = script; / Handle JSONP-style loading window jsonp = window jsonp | function( tmp ) data = tmp; success; complete; / Garbage collect window jsonp = undefined; try delete window jsonp ; catch(e) if ( head ) head.removeC
28、hild( script ); ; if ( s.dataType = script & s.cache = null ) s.cache = false; if ( s.cache = false & type = GET ) var ts = now; / try replacing _= if it is there var ret = s.url.replace(rts, $1_= + ts + $2); / if nothing was replaced, add timestamp to the end s.url = ret + (ret = s.url) ? (rquery.t
29、est(s.url) ? & : ?) + _= + ts : ); / If data is available, append data to url for get requests if ( s.data & type = GET ) s.url += (rquery.test(s.url) ? & : ?) + s.data; / Watch for a new set of requests if ( s.global & ! jQuery.active+ ) jQuery.event.trigger( ajaxStart ); / Matches an absolute URL,
30、 and saves the domain var parts = rurl.exec( s.url ), remote = parts & (parts1 & parts1 != location.protocol | parts2 != location.host); / If were requesting a remote document / and trying to load JSON or Script with a GET if ( s.dataType = script & type = GET & remote ) var head = document.getEleme
31、ntsByTagName(head)0 | document.documentElement; var script = document.createElement(script); script.src = s.url; if ( s.scriptCharset ) script.charset = s.scriptCharset; / Handle Script loading if ( !jsonp ) var done = false; / Attach handlers for all browsers script.onload = script.onreadystatechan
32、ge = function if ( !done & (!this.readyState | this.readyState = loaded | this.readyState = complete) ) done = true; success; complete; / Handle memory leak in IE script.onload = script.onreadystatechange = null; if ( head & script.parentNode ) head.removeChild( script ); ; / Use insertBefore instea
33、d of appendChild to circumvent an IE6 bug. / This arises when a base node is used (#2709 and #4378). head.insertBefore( script, head.firstChild ); / We handle everything using the script element injection return undefined; 上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值; 关注第14行,这一
34、行相当关键,注定了我们的结果最终是 ;然后是构造Script片段,第95行在Head中添加该片段,修成正果; 不仅仅是jQuery,很多js框架都是用了同样的跨域方案,这就是getJSON跨域的原理。 jQuery使用ajax跨域请求获取数据 跨域这个词应用非常频繁,主要是因为安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容)。本文给大家介绍jQuery使用ajax跨域请求获取数据,需要的朋友可以参考下 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容)
35、,因为我们在日常的项目开发时会不可避免的需要进行跨域操作,所以跨域能力也算是前端工程师的基本功之一。 var webMethod = http:/localhost:54473/Service1.asmx/HelloWorld; jQuery.support.cors = true; /之前没有加这句老是提示no transport,我没去深想。 $.ajax ( type: POST, contentType: application/x-www-form-urlencoded, dataType: html, url: http:/www.*.com, /这里是网址 success:fun
36、ction(data)alert(data);, timeout:30000, error: function (XMLHttpRequest, textStatus, errorThrown) alert(errorThrown); ); 参数 options 类型:Object 可选。AJAX 请求设置。所有选项都是可选的。 async 类型:Boolean 默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。 注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。 beforeSend(XHR) 类型:Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。 XMLHttpRequest 对象是唯一的参数。 这是一个 Ajax 事件。如果返回 false 可以取消本次 ajax 请求。 cache 类型:Boolean 默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。 jQue