什么是跨域?

简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”。而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。

具体策略限制情况可看下表:

URL 说明 允许通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同协议 不允许
http://www.a.com/a.js
http://127.0.0.100/b.js
域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二级域名(同上) 不允许
http://www.a.com/a.js
http://www.b.com/b.js
不同域名 不允许

什么是JSONP?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,而JSONP(JSON with Padding)则是JSON 的一种“使用模式”,通过这种模式可以实现数据的跨域获取。

JSONP跨域的原理

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。

举个例子,假如需要从服务器(http://www.a.com/user?id=123)获取的数据如下:

  1. {"id": 123, "name" : 张三, "age": 17}

那么,使用JSONP方式请求(http://www.a.com/user?id=123?callback=foo)的数据将会是如下:

  1. foo({"id": 123, "name" : 张三, "age": 17});

当然,如果服务端考虑得更加充分,返回的数据可能如下:

  1. try{foo({"id": 123, "name" : 张三, "age": 17});}catch(e){}

这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123?callback=foo:


便可以使用foo函数来调用返回的数据了。

在jQuery中如何通过JSONP来跨域获取数据

第一种方法是在ajax函数中设置dataType为'jsonp':

  1. $.ajax({
  2. dataType: 'jsonp',
  3. url: 'http://www.a.com/user?id=123',
  4. success: function(data){
  5. //处理data数据
  6. }
  7. });

第二种方法是利用getJSON来实现,只要在地址中加上callback=?参数即可:

  1. $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
  2. //处理data数据
  3. });

也可以简单地使用getScript方法:

  1. //此时也可以在函数外定义foo方法
  2. function foo(data){
  3. //处理data数据
  4. }
  5. $.getJSON('http://www.a.com/user?id=123&callback=foo');

JSONP的应用

JSONP在开放API中可以起到非常重要的作用,开放API是运用在开发者自己的应用上,而许多应用往往是在开发者的服务器上而不是在新浪微博的服务器上,因此跨域请求数据成为开发者们所需要解决的一大问题,广大开放平台应该实现对JSONP的支持,这一点新浪微博开放平台便做的非常好(虽然某些API里没有说明,但实际上是可以使用JSONP方式调用的)。

1、页面请求

function complete(){

var data = {
"enterprise_id":"8316",
"receiver_name":"王敏", 
"province_code":"110000",
"city_code":"110100",
"district_code":"110102",
"province_name":"北京市",
"city_name":"市辖区",
"district_name":"西城区",
"address":"这里是详细地址",
"contact_phone":"18721703659",
"default_address":"0"
};
$.ajax({
url:"http://usermanage.yaoex.com:8080/enterpriseInfo/saveReceiverAddress",
data:data,
dataType :'JSONP',
jsonp: "callbackSaveAddress",
jsonpCallback:"success_jsonp",
contentType: "application/json;charset=utf-8",
success: function (data) {
console.info(data);
}
});
}

2、服务器响应

/**
* 新增收发货地址信息
* @return
* @throws Exception
* {"enterprise_id":"8316","receiver_name":"小小蔡芽", "province_code":"110000","city_code":"110100","district_code":"110102","province_name":"北京市","city_name":"市辖区","district_name":"西城区","address":"这里是详细地址","contact_phone":"18721703659","default_address":"0"}
*/
@RequestMapping(value = "/saveReceiverAddress")
@ResponseBody
public String saveReceiverAddress(HttpServletRequest request,@RequestBody UsermanageReceiverAddress usermanageReceiverAddress) {
String jsonpCallback = request.getParameter("callbackSaveAddress");
Map<String, Object> resp = new HashMap<String, Object>();
try {
//获取用户信息
User user = UsermanageUserUtil.getCurrentUser(request);
if (null == user) {
resp.put("result", "error");
resp.put("msg", " 未能正常获取登录用户信息!");
logger.info(" 未能正常获取登录用户信息!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
usermanageReceiverAddress.setEnterprise_id(String.valueOf(user.getEnterprise_id()));
List<UsermanageReceiverAddress> usermanageReceiverAddressList= userManageEnterpriseService.queryReceiverAddress(String.valueOf(user.getEnterprise_id()));
if(null != usermanageReceiverAddressList && usermanageReceiverAddressList.size()>=10){
resp.put("result", "error");
resp.put("msg","添加失败,您只能保存10条收发货地址信息!");
logger.info("添加失败,您只能保存10条收发货地址信息!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
//新增地址插入正式表
userManageEnterpriseService.saveAddress(usermanageReceiverAddress);
resp.put("result", "success");
resp.put("msg", "地址保存成功!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
} catch (Exception e) {
logger.error(e.getMessage());
resp.put("result", "error");
resp.put("msg", "地址保存失败!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
}

jsonp处理跨域的更多相关文章

  1. 使用XHR2或Jsonp实现跨域以及实现原理

    我们直接使用XMLHttpRequset请求外部接口 会发现 报这个错误 其实浏览器成功发送请求并拿回了数据  只是浏览器的同源策略 禁止了获取  在xhr2 服务器端支持跨域 需要在响应头增加 Ac ...

  2. JSONP实现跨域

    首先提出:什么是跨域?如何解决跨域? 跨域可以简单的理解为从一个域名访问另一个域名,由于javascript的同源政策的限制,出于安全的考虑,不允许浏览器这么做.比如a.com 域名下的js无法操作b ...

  3. 跨域解决方案二:使用JSONP实现跨域

    跨域的实现方式有多种,除了 上篇文章 提到的CORS外,常见的还有JSONP.HTML5.Flash.iframe.xhr2等. 这篇文章对JSONP的跨域原理进行了探索,并将我的心得记录在这里和大家 ...

  4. 转(JSONP处理跨域事件)

     前言: 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Soc ...

  5. jsonp实现跨域访问

    要实现JSONP跨域访问,首先就要了解什么是跨域?然后JSONP与JSON的关系? 1.什么是跨域? 跨域简单的说就是一个域名下的程序和另一个域名下的程序做数据交互.比如说:现有一个http://ww ...

  6. 关于使用Jsonp做跨域请求

    今天在使用Jsonp做跨域请求的练习时碰上这样一个问题 代码如下 <!DOCTYPE html> <html> <head> <meta charset=&q ...

  7. 使用JSONP实现跨域

    什么是跨域? 简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即"同源策略".而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通 ...

  8. AJAX跨域问题解决方法(2)——JSONP解决跨域

    JSONP是什么?JSON全称为JSON with Padding,是JSON的一种补充的使用方式,不是官方协议. 使用JSONP服务器后台要改动吗?JSONP不同于一般的ajax请求返回json对象 ...

  9. 跨域 - 自定义 jsonp实现跨域

    问题:在现代浏览器中默认是不允许跨域. 办法:通过jsonp实现跨域   在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的.但是,在页面上引入不同域上的js脚本文件却是 ...

  10. 什么是同源策略,什么是跨域,如何跨域,Jsonp/CORS跨域

    同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响. 可以说Web是构建在同源策略基础之上 ...

随机推荐

  1. SQL SERVER 2012 第三章 T-SQL 基本语句 having子句

    SELECT ManagerID AS Manager,COUNT(*) AS Reports FROM Human.Resources.Employee2 WHERE EmployeeID !=5 ...

  2. softmax函数理解

    https://www.zhihu.com/question/23765351   因为这里不太方便编辑公式,所以很多公式推导的细节都已经略去了,如果对相关数学表述感兴趣的话,请戳这里的链接Softm ...

  3. 从零开始写STL—set/map

    这一部分只要把搜索树中暴露的接口封装一下,做一些改动. set源码剖析 template<typename T> class set { public: typedef T key_typ ...

  4. T1231 最优布线 codevs

    http://codevs.cn/problem/1231/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题目描述 Description 学校需要将n ...

  5. [Bzoj3668][Noi2014]起床困难综合症(位运算)

    3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2612  Solved: 1500[Submit][St ...

  6. eclipse提速02 - eclipse.ini优化

    给eclipse执行jvm.它可以让你使用自己的jdk,而不是系统环境变量所指定的jdk -vm /path/to/your/java 使用最新的jdk来运行eclipse.使用最新的jdk要好很多. ...

  7. DELPHI7调用BERLIN中间件的中文字段名乱码的解决办法

    MSSQL数据库的表使用中文字段名,BERLIN开发的DATASNAP中间件,DELPHI7调用中间件的查询方法返回数据给CLIENTDATASET.DATA,发现中文字段名乱码,中文字段名的值可以正 ...

  8. topcoder srm 610

    div1 250pt: 题意:100*100的01矩阵,找出来面积最大的“类似国际象棋棋盘”的子矩阵. 解法:枚举矩阵宽(水平方向)的起点和终点,然后利用尺取法来找到每个固定宽度下的最大矩阵,不断更新 ...

  9. kindle】扫描版PDF完美切割六寸

    kindle]扫描版PDF完美切割六寸  半夏 2013-11-05 18:36:01     软件来源记不清了..连使用说明的网址都找不到了,自己写一下使用方法大家凑合一下呗~    软件是大牛写的 ...

  10. 获取Windows用户所有的账户名

    /// <summary> /// 设置用户密码 /// </summary> [DllImport("Netapi32.dll")] extern sta ...