什么是跨域?

简单的来说,出于安全方面的考虑,页面中的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. POJ 2749 2SAT判定+二分

    题意:图上n个点,使每个点都与俩个中转点的其中一个相连(二选一,典型2-sat),并使任意两点最大 距离最小(最大最小,2分答案),有些点相互hata,不能选同一个中转点,有些点相互LOVE,必需选相 ...

  2. hdu 1429 bfs+二进制状态压缩

    开始时候只用了BFS,显然超时啊,必然在结构体里加一个数组什么的判重啊,开始用的一个BOOL数组,显然还是不行,复杂度高,每次都要遍历数组来判重:后百度之,学习了二进制状态压缩,其实就用一个二进制数来 ...

  3. CSY版最大团,速度快一倍

    #include <bits/stdc++.h> using namespace std; #define REP(i, n) for(int i(0); i < (n); ++i) ...

  4. ATcoder 1983 BBQ Hard

    E - BBQ Hard Time limit : 2sec / Memory limit : 256MB Score : 1400 points Problem Statement Snuke is ...

  5. 【永久激活,视频教程,超级详细】IntelliJ idea 2018.3安装+激活+汉化

    简介 IDEA 全称IntelliJ IDEA,是用于java语言开发的集成环境(也可用于其他语言),IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构. ...

  6. struts2 自己定义表单

    自己定义表单一定会涉及<s:iterator/>迭代,一个复杂的自己定义表单可能会嵌套n多层迭代. 比方一个自己定义一个问卷调查页面涉及3个模型:一个Survey代表一个调查.一个Page ...

  7. JMeter Web测试快速入门教程

    学习前的准备 学习本教程前,你的电脑上至少应该有Apache JMeter这款软件.如果你没有,点击此处下载. 当你点进去后,你会发现它是一个依赖Java的软件 因此如果你电脑上没有Java环境,你应 ...

  8. maven目录结构介绍篇

    bin  该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath喝相关的java系统属性 mvn是基于UNIX平台shell脚本,mvn.bat是基于Windows平台的 ...

  9. python dig 模拟—— DGA域名判定用

    #!/usr/bin/env python import dns.resolver, sys def get_domain_ip(domain): """Get the ...

  10. Java 内存管理、JVM 工作原理与 Java 运行时系统

    Java 虚拟机规范中说明:所有的对象实例(all class instances)以及数组都要在堆上分配: the heap is the runtime data area from which ...