Ajax跨域原理及JQuery中的实现
AJAX 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新。但是出于安全的考虑,ajax不允许跨域通信。如果尝试从不同的域请求数据,就会出现错误。如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?
1、Ajax为什么不能跨域?到底是卡在哪个环节了?(下面项目中具体说,这里先说下结论)。 Ajax其实就是向服务器发送一个GET或POST请求,然后取得服务器响应结果,返回客户端。跨域出现错误的地方正是请求到了数据,拿不回去,所以我们ajax跨域的问题就可以转化为数据怎么拿回去的问题。
2、既然不能直接访问第三方站点,我们可以在服务器上面做代理,通过ajax向代理发送请求,代理获得数据后在返回给客户端,当然这是一种解决办法,但是一次请求要从客户端经过代理到第三方站点,然后再原路返回,响应速度是个问题。
3、我们发现我们可以将一些js、css等文件放在第三方的服务器上面,如CDN等来加快网页的打开速度,这样是没有任何问题的,也就是说web页面可以加载放在任意站点的js、css、图片等资源,不会受到"跨域"的影响。这个时候,我们会想到:既然我们可以调用第三方站点的js,那么如果我们将数据放到第三方站点的js中不就可以将数据带到客户端了吗?
下面我们来做一个实验,来验证一下我们的猜想成不成立:
打开Visual Studio,新建一个Web项目,这里用WebForm,然后我们在项目中添加一个名为remoteJs的js文件,写入如下代码:
function GetRemoteData() {
return "remote data";
}
很简单,就一个方法,返回一个字符串,下面我们来写一个客户端调用,既然是跨域,那就写个html静态页面来测试吧,新建local.html,输入以下代码:

<!DOCTYPE html>
<html>
<head>
<title>本地站点</title>
<meta charset="UTF-8">
<script type="text/javascript" src="http://localhost:4071/remoteJs.js"></script>
</head>
<script type="text/javascript">
var data = GetRemoteData();
alert(data);
</script>
<body> </body>
</html>

让我们的Web项目跑起来,然后打开local.html,可以看到弹出一个窗口,显示信息remote data。这里证明我们的想法是正确的。接下来的问题是,我们如何根据需要发送请求和获取请求的结果呢?下面我们来认识一下JSONP。
1、什么是JSONP
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。其核心思想是利用JS标签里面的跨域特性进行跨域数据访问,在JS标签里面存在的是一个跨域的URL,实际执行的时候通过这个URL获得一段字符串,这段返回的字符串必须是一个合法的JS调用,通过EVAL这个字符串来完成对获得的数据的处理。
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2、JSONP的实现
下面我们通过一个例子来说明一下JSONP是如何实现ajax跨域请求的。这里我们模拟图书馆图书的查询,在刚刚我们建立的web项目里面添加一个名为SearchBook的一般处理程序,写入如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace BookLibrary
{
public class SearchBook : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string callback = context.Request["callback"];
context.Response.Write(callback + "({'BookName':'English','Pages':562})");
} public bool IsReusable
{
get
{
return false;
}
}
}
}

暂时先不解释,我们写完客户端看到效果后在详细说明,然后修改刚刚的local.html,代码如下:

<!DOCTYPE html>
<html>
<head>
<title>跨域请求</title>
<meta charset="UTF-8">
</head>
<body>
<input type="button" value="发送请求" onclick="GetAjaxData();" />
</body>
<script type="text/javascript">
var GetData = function (data) {
alert(data.BookName + " " + data.Pages);
};
function GetAjaxData(){
var url = "http://localhost:4071/SearchBook.ashx?callback=GetData";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
} </script>
</html>

这个html页面有一个按钮,绑定方法GetAjaxData,当我们单击发送请求时,就会向Web站点发送请求,获取查询的数据,我们让Web站点跑起来,然后打开local.html,单击按钮,看到弹出如下信息:
我们成功的取得了web站点的数据,实现了跨域请求。下面我们来说一下他的实现原理:
var url = "http://localhost:4071/SearchBook.ashx?callback=GetData";
这一行代码我们定义了请求的url,问号前面的是web站点一般处理程序SearchBook的地址,问号后面我们传入了一个参数callback,值为GetData,也就是我们上面定义的方法名,及回调函数名称。当然我们可以传入更多的参数。
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
这三行代码就是添加script节点,url指向第三方站点,执行结果如图:
那么我们刚刚写的一般处理程序返回的结果就不用说了吧,他就是返回一个字符串,内容为:
看到这里清楚了吧,就是第三方站点生成一个对回调函数的调用,传入查询结果,然后通过<script>加载到客户端执行。看到这里是不是想到了什么?是不是和C#里面的委托有些共同点?整体流程如图:
可以看到,整个过程,本地站点一直处于主动的地位,主动的发送请求,主动的加载远程js.而第三方站点则处于被动的响应。
3、普通Ajax请求在哪个环节出错了
下面,我们用JQuery的ajax来说明一下ajax请求到底是卡在哪个环节了,修改GetAjaxData方法如下:

$.ajax({
type: "get",
async: false,
url: "http://localhost:4071/SearchBook.ashx",
dataType: "text",
success: function (data) {
alert(data.BookName + " " + data.Pages);
},
error: function () {
alert('fail');
}
});

在SearchBook里面context.Response.Write(callback + "({'BookName':'English','Pages':562})");这行下端点,然后运行,会发现可以走到断点,然后就出错了。
4、用JQuery实现ajax跨域
其实JQuery里面也封装了跨域的ajax方法,我们来看一下上面的方法用JQuery怎么写:

<script type="text/javascript">
function GetAjaxData() {
$.ajax({
type: "get",
async: false,
url: "http://localhost:4071/SearchBook.ashx",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,标识jsonp回调函数名(一般为:callback)
jsonpCallback: "GetData",//callback的function名称
success: function (data) {
alert(data.BookName + " " + data.Pages);
},
error: function () {
alert('fail');
}
});
}
</script>

注意,JQuery写法里面Url后面就不用再写?来传递参数了,jsonp的值相当于?后面的值及参数名称,jsonpCallback的值就是参数的value.success就是执行成功后调用的方法。
哎,不对啊,怎么没有GetData方法了?JQuery到底是怎么实现的呢?下面我们来调试一下JQuery,来看一下里面是怎么实现的,调试js,当然还是要用Chrome,看图:
这张图中,我们看到有个对象s,在做url拼接操作,看到选中那行了吧,?后面拼的是s.jsonp,最后拼接的是callbackName.继续向下走:
我们看到s.url的值,为拼接后的值,是不是和我们自己写的js代码里面的url一模一样,继续向下走:
我们看到JQuery又在刚刚的url后面添加下划线等号,然后又跟了一串数字,至于什么用,我也说不上来,继续向下走:
看到了什么,success方法,哈哈,这是JQuery在变量参数,继续走:
看到什么了?没错,这就是JQuery最终调用的方法,最后一行代码,添加了script节点,和我自己写js实现的原理一样。继续向下走,看看还有什么:
看到JQuery执行完后,又删除了刚刚添加的script节点,还是JQuery想的周到啊~~
下面我们来看一下,我们自己写的js执行后的DOM结构:
看到了吧,script节点会随着请求的次数一路飙升,不过并不会引起错误,刷新后就消失了。而JQuery执行后,DOM结构是不变的。
1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
2、ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是通过HTTP来动态添加<script>标签来调用服务器提供的js脚本。
3、其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
4、jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
5、jsonp整个过程中,本地站点一直处于主动的地位,主动的发送请求,主动的加载远程js.而第三方站点则处于被动的响应。
作者:雲霏霏
QQ交流群:243633526
Ajax跨域原理及JQuery中的实现的更多相关文章
- 浅析Ajax跨域原理及JQuery中的实现分析
AJAX 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新.但是出于安全的考虑,ajax不允许跨域通信.如果尝试从不同的域请求数据,就会出现错误.如果能控制数据驻留的远程服务器 ...
- Ajax跨域访问wcf服务中所遇到的问题总结。
工具说明:vs2012,sql server 2008R2 1.首先,通过vs2012建立一个wcf服务项目,建立好之后.再新开一个vs2012 建立web项目,通过jQuery的ajax方法访问服务 ...
- ajax跨域原理以及解决方案
说明 跨域主要是由于浏览器的“同源策略”引起,分为多种类型,本文主要探讨Ajax请求跨域问题 前言 强烈推荐阅读参考来源中的文章,能够快速帮助了解跨域的原理 参考来源 本文参考了以下来源 浏览器同源政 ...
- 跨域问题及jQuery中Ajax传参的讲解
1.跨域:不再同一服务器下,就是协议,域名,端口,有一个不一样: 浏览器对于javascript的同源策略的限制: 案例: 以 http://172.164.23:8088/ 为例 相同域名:172. ...
- ajax跨域原理以及jsonp使用
jsonp介绍: JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题. 由于同源策略,一般来说位于 server1.example. ...
- ajax跨域请求在IE8中存在的问题
从没打算怎么去兼容老版本IE,毕竟微软自己都放弃了,可是最近做好的东西在所有的IE下都会出问题:GetJson不执行 本来觉得挺简单的,度娘也给出了一大堆的解决方案,可惜,基本上都是在说缓存,实际上并 ...
- 前端筑基篇(一)->ajax跨域原理以及解决方案
说明 跨域主要是由于浏览器的“同源策略”引起,分为多种类型,本文主要探讨Ajax请求跨域问题 前言 参考来源 什么是跨域 ajax跨域的表现 跨域的原理 如何解决跨域问题 JSONP方式解决跨域问题 ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)
Ajax跨域问题及解决方案 目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...
随机推荐
- MVC5个人用户账户身份验证集成google和facebook的OAuth2登陆
最终效果 官方文档:MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on 内容简介:上面传送门的博客中讲解了如何在M ...
- 学习英语每日一 On the house. 赠品
tp=webp" alt=""> On the house. 免费赠送.我们之前学过请客能够说I'll buy you something. 事实上还有一种说法是I ...
- K60 启动过程分析
很高兴老师借给我一K60的开发板,趁着暑假好好鼓捣鼓捣! 有了上图的过程分析我想心里大概有个低了吧! 以下看代码: /* CodeWarrior ARM Runtime Support Library ...
- SQL Server审计功能入门:CDC(Change Data Capture)
原文:SQL Server审计功能入门:CDC(Change Data Capture) 介绍 SQL Server 2008引入了CDC(Change Data Capture),它能记录: 1. ...
- 2014年TI杯大学生电子设计竞赛地区赛使用仪器及器件、设备
2014年TI杯大学生电子设计竞赛地区赛使用仪器及器件.设备 a) 3A/30V双路稳压电源(可并联): b) 60MHz示波器: c) 三位半数字万用 ...
- Think in Java(一):Java基础
一. OOP的特点 (1) 万物皆为对象; (2) 程序是对象的集合,他们通过发送信息来告诉彼此所要做的; (3) 每一个对象都有自己的由其它对象所构成的存储; (4) 每一个对象都拥有它的类型; ( ...
- Scan IP relocate/failover其它段后不能ping通过
或手动集群重启单个节点srvctl relocate scan_listener后.群集网络段ping IP,VIP.SCAN IP正常.其他段ping SCAN IP 不通.其原因是,该路由ARP表 ...
- 苹果(APPLE)开发人员账号说明及注冊流程(99美元公司版/个人版及299美元企业版)
APPLE的政策是,要公布到APP STORE必须用99美元的个人版或公司版Apple Developer Programs,要在非商店外下载仅仅能使用299美元的企业版iOS Developer E ...
- SAP RFC 函数来创建 Java呼叫 学习总结 一步一步的插图
前言 该公司很快就接到了一个项目,SAP有接口.让我们做老大SAP.首先SAP联系.但发展从来没有打过.本周集中在这一个研究. 各种碰壁,SAP该系统让我怎么说? 算了.说多了都是泪,以下附上本周学习 ...
- (札记)Java应用架构设计-模块化模式与OSGi
本书主要模块化模式的优点.模块化方法与模式.OSGi简单使用等内容.分3大部分: 第一部分介绍了模块化概念.为什么要模块化,以及一些模块化要考虑的东西,如模块粒度,依赖关系,重用性灵活性等. 第二部分 ...