浅析JSONP-解决Ajax跨域访问问题
浅析JSONP-解决Ajax跨域访问问题
很久没有写随笔了,总是感觉没时间,其实时间就是。。。废话少说,前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息。实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问题了,后台服务调用没有响应,怎么回事?代码没怎么改动,唯一修改的地方就是jQuery的ajax方法中的url地址。难道是这里的问题,经过检查和调试,发现原来是同源策略在作怪,我们知道,JavaScript或jQuery是在Web前端开发中经常使用的动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same- Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档或脚本 在同一域名下的内容。不同域名下的脚本不能互相访问,即便是子域也不行。关于同源策略,读者可百度更详细的解释,这里不再赘述。
但是有时候又不可避免地需要进行跨域操作,这时候“同源策略”就是一个限制了,怎么办呢?采用JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并探讨下JSONP跨域的原理。
这里提到了JSONP,那有人就问了,它同JSON有什么区别不同和区别呢,接下我们就来看看,百度百科有以下说明:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速度快)。
JSONP(JSON with Padding)是JSON的 一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
到这里,应该明白了,JSON是一种轻量级的数据交换格式,像xml一样,是用来描述数据间的。JSONP是一种使用JSON数据的方式,返回的不是JSON对象,是包含JSON对象的javaScript脚本。
那JSONP是如何工作的呢,我们知道,由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。若要跨域请求出于安全性考虑是不行的,但是我们发现,Web页面上调用js文件时则不受是否跨域的影响,而且拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>,这时候,聪明的程序猿就想到了变通的方法,如果要进行跨域请求, 通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递 javascript对象。即在跨域的服务端生成JSON数据,然后包装成script脚本回传,着不就突破同源策略的限制,解决了跨域访问的问题了么。
下面我们就看下怎么实现:
前端代码:
function CallWebServiceByJsonp() {
$("#SubEquipmentDetails").html('');
$.ajax({
type: "GET",
cache: false,
url: "http://servername/webservice/webservice.asmx/GetSingleInfo",
data: { strCparent: $("#Equipment_ID").val() },
dataType: "jsonp",
//jsonp: "callback",
jsonpCallback: "OnGetMemberSuccessByjsonp"
});
} function OnGetMemberSuccessByjsonp(data) {
//处理data
alert(data);
}
后端的WebService代码:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public void GetSingleInfo(string strCparent)
{
string ret = string.Empty;
HttpContext.Current.Response.ContentType = "application/json;charset=utf-8";
string jsonCallBackFunName = HttpContext.Current.Request.Params["callback"].ToString();
//string jsonCallBackFunName1 = HttpContext.Current.Request.QueryString["callback"].Trim(); //上面代码必须
//中间代码执行自己的业务操作,可返回自己的任意信息(多数据类型) BLL.equipment eq_bll = new BLL.equipment();
List<Model.equipment> equipmentList = new List<Model.equipment>();
equipmentList = eq_bll.GetModelEquimentList(strCparent);
ret = JsonConvert.SerializeObject(equipmentList); //下面代码必须
HttpContext.Current.Response.Write(string.Format("{0}({1})", jsonCallBackFunName, ret));
HttpContext.Current.Response.End();
}
如上所示,前端的CallWebServiceByJsonp方法采用jQuery的ajax方法调用后端的Web服务GetSingleInfo方法,后台的GetSingleInfo方法,使用前端的回调方法OnGetMemberSuccessByjsonp包装后台的业务操作的JSON对象,返回给前端一段javascript片段执行。巧妙的解决了跨域访问问题。
JSONP的缺点:
JSONP不提供错误处理。如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。
浅析JSONP-解决Ajax跨域访问问题的更多相关文章
- 说说JSON和JSONP,浅析JSONP解决AJAX跨域问题
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...
- JSON和JSONP,浅析JSONP解决AJAX跨域问题
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...
- 使用JSONP彻底解决Ajax跨域访问Cookie Session的方案
最近做开发时要把图片文件放到另外一台服务器上(另外一个域名),因为这样分布式存放,网站打开速度会快很多.而我采用AJAX获取图片服务器上某用户的图片时遇到了问题,按照通常的方式无法获取信息,得到的Co ...
- 解决ajax跨域访问sessionid不一致问题
根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务器就会以为 ...
- jfinal 解决ajax 跨域访问--jsonp
JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的 js无法操作b.com或是c.a.com域名下的对象. ...
- JSONP解决ajax跨域问题
在A域名下,用ajax请求B域名下的请求,会报类似这样的错误:No 'Access-Control-Allow-Origin' header is present on the requested r ...
- jQuery中利用JSONP解决AJAX跨域问题
写在前面 跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨 ...
- express解决ajax跨域访问session失效问题
最近在学习express,就用以前做的项目来进行express前后端分离的练手了,在做登陆注册的时候发现跨域的时候,session的值是会失效的,导致session里面的数据获取为undefined, ...
- 【转】Php+ajax+jsonp解决ajax跨域问题
首先:jsonp是json用来跨域的一个东西. 原理是通过script标签的跨域特性来绕过同源策略. 发送端: $.ajax({ type : "post", url : &quo ...
随机推荐
- Sql:多行合并一行以及多条数据取时间最早的那条
有两个导数据的需求,1.一张表里面每一个订单号可能对应多条数据,每个单号返回时间最早的那条. 2.根据条件查询某个字段并按照逗号,合并在一起. 表类似结构如下: 第一条sql:select c.Id, ...
- 推荐一个简单、轻量、功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler定时器
在C#WINFORM或者是ASP.NET的WEB应用程序中,根据各种定时任务的需求,比如:每天的数据统计,每小时刷新系统缓存等等,这个时候我们得应用到定时器这个东东. .NET Framework有自 ...
- 成为一名优秀的Web前端开发者
本文记录了两位工程师为web开发者们所提出的多条建议,其中一位推荐了多种实用的工具与技术,而另一位则对于如何克服浏览器开发时所面临的挑战提出了诸多建议. Rebecca Murphey是来自于Baza ...
- HDFS副本存放策略
在client向DataNode写入block之前,会与NameNode有一次通信,由NameNode来选择指定数目的DataNode来存放副本.具体的副本选择策略在BlockPlacementPol ...
- 一些免费的WebService的服务网站
Endpoint: http://fy.webxml.com.cn/webservices/EnglishChinese.asmx Disco: http://fy.webxml.com.cn/web ...
- Linux——makefile
1.vim Makefile 或 vim makefile 2. targetName:a.o b.o #targetFileName:A.c B.c ,split with a space gc ...
- 一张关于docker版本的图
今天安装了windows内测版的docker,的确是是把vitualbox换成了hyper-v,如左图,server的os 还是linux.不过之前在nanoserver上装的docker 也的确是原 ...
- js中,全局变量与直接添加在window属性的区别
在js中定义的全局变量是挂在window下的,而window的属性也一样,那么这两者有什么区别呢? 其实这两者还是有小小的区别的,全局变量是不能通过delete操作符删除的,而直接定义在window上 ...
- 005-Scala数组操作实战详解
005-Scala数组操作实战详解 Worksheet的使用 交互式命令执行平台 记得每次要保存才会出相应的结果 数组的基本操作 数组的下标是从0开始和Tuple不同 缓冲数组ArrayBuffer( ...
- nginx url重定向
nginx内部支持url rewrite,内部编译进去了rewrite模块,nginx的rewrite模块类似于apache的rewriterule功能:支持多种规则和正则表达式: 详细介绍如下: N ...