JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

同源策略限制

  同源策略限制:出于安全方面的考虑,浏览器阻止代码获得或者更改从另一个域名下获得的文件或者信息。也就是说我们的请求地址必须和当前网站的地指相同。同源策略通过隔离来实现对资源的保护。这个策略的历史非常悠久从Netscape Navigator 2.0时代就开始了。

什么是跨域?

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

JSONP跨域的原理

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

具体流程如下:

1. 首先在客户端注册一个callback, 然后把callback的名字传给服务器。

2. 此时,服务器先生成 json 数据,然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp,最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
3. 客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

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

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

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

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

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

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

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

function executeJsonp(url){
  var eleScript= document.createElement("script");
  eleScript.type = "text/javascript";
  eleScript.src = url;
  document.getElementsByTagName("head")[0].appendChild(eleScript);
} function foo(data){
for(var p in data){
console.log(data[p]);
}
} var url = "http://www.a.com/user?id=123?callback=foo";
executeJsonp(url)

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

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

$.ajax({
dataType: 'jsonp',
url: 'http://www.a.com/user?id=123',
success: function(data){
//处理data数据
}
});
getJsonp: function(url, param, callback) {
$.ajax({
url: url,
data: param,
dataType: "jsonp",
success: callback,
error: function(data){
alert('网络异常,请稍后再试!');
}
})
}

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

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

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

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

JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

jsonp跨域问题的更多相关文章

  1. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  2. 借助node实战JSONP跨域

    一.前言: 浏览器安全是基于同源策略的.所谓同源策略就是三相同: 1.协议相同: 2.域名相同: 3.端口相同. 但,凡事都是有利弊,同源策略也导致了我们想用AJAX跨域请求,但NO!!为了规避这种限 ...

  3. jsonp跨域+ashx(示例)

    前言 做B/S项目的时候,我们一般使用jquery+ashx来实现异步的一些操作,比如后台获取一些数据到前台,但是如果ashx文件不在本项目下,引用的是别的域下的文件,这时候就访问不了.关于jsonp ...

  4. Jsonp跨域访问

    很早之前看过好几篇跨域访问的文章,然后做项目的时候基本没有遇到跨域访问的问题.不过该来的还是会来,前些天终于让我遇到了.于是重温了一下原理这些,再进行实战.于是现在也敢通过实战后的一些理解来和大家分享 ...

  5. jsonp 跨域请求

    背景: JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为"Same-Origin Policy"(同源 ...

  6. 我的jsonp跨域问题

    关于jsonp跨域问题,在这个方面也是了解一点点,先记录下来,主要作为以后查看,之前下载并安装过wampserver,了解到了jsonp和json的区别,现在谈谈跨域这个问题: 首先什么是跨域,简单地 ...

  7. jsonP跨域调用

    -------------------------------------jsonP跨域调用------------------------------------- <div class=&q ...

  8. JSONP跨域的原理解析( 一种脚本注入行为)

    JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制, 被称为“some-Origin Policy”(同源策略).这一策略对于Jav ...

  9. JSONP跨域的原理解析

    JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为“Same- Origin Policy”(同源策略).这一策略对于Jav ...

随机推荐

  1. (转)Windows下的Memcached安装与使用

    WHAT Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memc ...

  2. Linux磁盘管理

    本系列的博客来自于:http://www.92csz.com/study/linux/ 在此,感谢原作者提供的入门知识 这个系列的博客的目的在于将比较常用的liunx命令从作者的文章中摘录下来,供自己 ...

  3. JavaFX結合 JDBC, Servlet, Swing, Google Map及動態產生比例圖 (1):NetBeans 寫 Servlet (转帖)

    JavaFX結合 JDBC, Servlet, Swing, Google Map及動態產生比例圖 (1):NetBeans 寫 Servlet 功能:這支程式的主要功能是將 javafx 與 swi ...

  4. 移动端web开发进阶

    三个月前曾写过一篇跨终端响应式页面设计入门的博客,上了博客园头条也得到了不少关注,今天想在这篇博客的基础上,继续写一篇进阶的文章. 补充 基于“入门”一文,我想再补充几个基础知识点,主要都是针对iOS ...

  5. 【腾讯Bugly干货分享】腾讯验证码的十二年

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/581301b146dfb1456904df8d Dev Club 是一个交流移动 ...

  6. 【腾讯Bugly干货分享】QFix探索之路—手Q热补丁轻量级方案

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ff5832bb8fec206ce2185d 导语 QFix 是手Q团队近期推 ...

  7. Backbone源码解析(一):Event模块

    Backbone是一个当下比较流行的MVC框架.它主要分为以下几个模块: Events, View, Model, Collection, History, Router等几大模块.它强制依赖unde ...

  8. 使用Guava提供的transform批量转换

    实际开发了,为了快速查询,我们会把日期以Long类型的方式存储到数据库中,比如20000000000000L,但显示的时候,要完整的日期,即yyyy-MM-dd的格式显示. 这个时候,我们就可以使用C ...

  9. [安卓] 15、用NFC解锁手机并自动打开应用

    最近接到一个项目:将手机放到一个带有NFC卡的底座上手机会自动解锁,然后打开相应的应用 本人用:杭州公交通用卡做为NFC卡+Coolpad手机进行试验 效果如下: 1.手机本身带有图案锁,输对图案才能 ...

  10. JavaScript 误区

    接触JavaScript两年多遇到过各种错误,其中有一些让人防不胜防,原来对JavaScript的误会如此之深,仅以此文总结一下常见的各种想当然的误区 String replace string的re ...