同源策略,它是由Netscape提出的一个著名的安全策略,现在所有的可支持javascript的浏览器都会使用这个策略。

为什么需要同源策略,这里举个例子:

假 设现在没有同源策略,会发生什么事情呢?大家知道,JavaScript可以做很多东西,比如:读取/修改网页中某个值。恩,你现在打开了浏览器,在一 个tab窗口中打开了银行网站,在另外一个tab窗口中打开了一个恶意网站,而那个恶意网站挂了一个的专门修改银行信息的JavaScript,当你访问 这个恶意网站并且执行它JavaScript时,你的银行页面就会被这个JavaScript修改,后果会非常严重!而同源策略就为了防止这种事情发生.

比如说,浏览器的两个tab页中分别打开了http://www.baidu.com/index.html和http: //www.google.com/index.html,其中,JavaScript1和JavaScript3是属于百度的脚本,而 JavaScript2是属于谷歌的脚本,当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执 行,所谓同源,就是指域名、协议、端口相同。所以,tab1只能执行JavaScript1和JavaScript3脚本,而JavaScript2不能 执行,从而防止其他网页对本网页的非法篡改。

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

三、为什么使用JSONP?
由于 JSON 只是一种含有简单括号结构的纯文本,因此许多通道都可以交换 JSON 消息。因为同源策略的限制,
不能在与外部服务器进行通信的时候使用 XMLHttpRequest。而JSONP是一种可以绕过同源策略的方法,即通过使用 JSON 与 <
script> 标记相结合的方法,从服务端直接返回可执行的JavaScript函数调用或者JavaScript对象。

其实 jsonp 是个很简单的一个东西。主要是利用了 <script/>标签对javascript文档的动态解析来实现。(其实也可以用eval函数)。

<script type="text/javascript">
function jsonpCallback(result) {
alert(result.msg);
}
</script>
<script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback"></script>

其中 jsonCallback 是客户端注册的,获取跨域服务器上的json数据后,回调的函数。

http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback

这个 url 是跨域服务器取 json 数据的接口,参数为回调函数的名字,返回的格式为:

jsonpCallback({ msg:'this  is  json  data'})

Jsonp原理: 

首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的javascript文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数) .

其实说白了,就是客户端定义一个函数(如a),请求地址后服务器端返回的结果是调用a函数,需要的数据都放在了a函数的参数里面。

demo:

应为它用到的只是所有 HTML 元素中一个简单的 script 元素。看到这是不是觉得越发奇怪了?没关系,继续看下去就会茅厕(塞)顿开的,嘿嘿~来看个例子吧:

demo.html:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Demo</title>
</head>
<body>
<script type="text/javascript">
function say(words) {
alert(words);
}
</script>
<script type="text/javascript" src="demo.js"></script>
</body>
</html>

demo.js:

say("Hello, everyone!");

运行 demo.html 文件后,是不是看到写着“Hello, everyone!”的警告框了?你可能会觉得这个例子很简单,没什么了不起的,甚至会在想:这和 JSONP 有关系吗?那么,我可以很肯定的告诉你:有关系!而且,这个例子实际上就是 JSONP 的原型!你也许会想到,JSONP 不是访问远程数据的吗?对,试想一下,如果 demo.js 文件在其它域的服务器上呢?结果会不会出现问题?我也可以很负责的告诉你:不会!你可以将上面例子中的 demo.js 更改为:http://demo.hpyer.cn/php/jsonp.php?callback=say 再试一下。

现在,聪明的你应该已经明白 JSONP 到底是怎么回事了,那么,再来解释一下本节开头第一句话吧。看过 demo.js
文件的内容,应该知道,其只是对一个函数(通常称之为:回调函数)的调用,而需要交互的数据则通过参数形势进行返回。所以通过 JSONP
访问的服务器需要提供一个可以设置回调函数名的接口,就像
http://demo.hpyer.cn/php/jsonp.php?callback=say 中的 callback,所以,综上所述
JSONP 是需要服务器端的支持的。附上 jsonp.php 的源码:

<?php
$type = isset($_GET['type']) ? $_GET['type'] : '';
$callback = isset($_GET['callback']) ? $_GET['callback'] : '';
$json = '';
if ($type == 'json') {
$json = '{
"Image": {
"Width": ,
"Height": ,
"Title": "View from 15th Floor",
"Thumbnail": {
"Url": "http://www.example.com/image/481989943",
"Height": ,
"Width": ""
},
"IDs": [, , , ]
}
}';
} else {
$json = '"Hello, everyone!"';
}
if (!empty($callback)) {
$json = $callback . '(' . $json . ')';
}
echo $json;

jquery 中的应用:
自 1.2 版本起,jQuery 加入了对 JSONP 的支持。我们可以很容易的利用 $.getJSON() 方法(或者其它基于 $.ajax() 的方法),来跨域加载 JSON 数据。来个例子吧:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Demo</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function do_jsonp() {
$.getJSON("http://demo.hpyer.cn/php/jsonp.php?type=json&callback=?",
function(data) {
$('#result').val('data.Image.IDs: ' + data.Image.IDs);
});
}
</script>
</head>
<body>
<a href="javascript:do_jsonp();">Click me</a><br />
<textarea id="result" cols="" rows=""></textarea>
</body>
</html>

你可能注意到上面的例子中,url 被写成了 http://demo.hpyer.cn/php/jsonp.php?type=json&callback=?,需要说明的是,这个问号会 被 jQuery 自动替换为回调函数的函数名(如果是一个匿名函数,jQuery 会自动生成一个带时间戳的函数名)。

看我在项目中的一个例子:

//定义Ajax函数
function ajaxFun() {
var timeStamp = Math.floor(new Date().getTime() / );
var url = "http://apiso.alidemo.3gpp.cn/httpserver/cp/yisou/ali_feedback_interface.php?callback=jsonpCallback&feedbacktype=add&type=" + feedbackNumber + "&book=" + me.mixedInfo.title + "&author=" + me.mixedInfo.author + "&chapter=" + me.mixedInfo.cname + "&chapterid=" + me.mixedInfo.cid + "&questiondesc=" + text + "&platform=1&t=" + timeStamp + "&sn=" + md5("d30fcd1a9f1900fa049b4766e0a275e1" + timeStamp);
var scriptObj = document.createElement("script");
scriptObj.src = url;
scriptObj.id = "jsonpScript";
document.body.appendChild(scriptObj);
//jsonp回调函数,jsonpCallback必须为全局函数,因为jsonp返回的是在全局环境中执行函数的语句,即jsonpCallback(data)
window.jsonpCallback = function(data) {
switch (data.code) {
case "":
novel.readerPrompt('提交成功,即将返回……', , function() {
window.history.go(-);
});
break;
case "":
novel.readerPrompt('提交失败。', );
break;
case "":
novel.readerPrompt('提交失败,验证失败。', );
break;
}
//成功后删除scriptObj,后面的setTimeout就不会执行了
if (document.getElementById("jsonpScript")) {
document.body.removeChild(scriptObj);
}
}
//设置超时,超时的话直接显示提交成功
setTimeout(function() {
if (document.getElementById("jsonpScript")) {
document.body.removeChild(scriptObj);
novel.readerPrompt('提交成功,即将返回……', , function() {
window.history.go(-);
});
}
}, );
}
ajaxFun();

关于javascript跨域及JSONP的原理与应用的更多相关文章

  1. jQuery(三) javascript跨域问题(JSONP解决)

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  2. javascript 跨域问题 jsonp

    转载:http://www.cnblogs.com/choon/p/5393682.html demo 用动态创建<script></script>节点的方式实现了跨域HTTP ...

  3. 跨域和jsonp的原理

    什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. 所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子: h ...

  4. 说一说javascript跨域和jsonp

    同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规 ...

  5. 前端跨域之Jsonp实现原理及.Net下Jsonp的实现

    jsonp的本质是通过script标签的src属性请求到服务端,拿到到服务端返回的数据 ,因为src是可以跨域的.前端通过src发送跨域请求时在请求的url带上回调函数,服务端收到请求时,接受前端传过 ...

  6. 利用javascript跨域访问cookie之广告推广

    在上一篇<说一说javascript跨域和jsonp>中,利用JSONP进行了跨域的数据访问,利用JS本身的跨域能力在远端生成HTML结构的方式完成了一个小广告. 在实际应用中, 跨域使用 ...

  7. JavaScript 跨域漫游

    前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...

  8. javascript跨域传递消息 / 服务器实时推送总结

    参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...

  9. jquery跨域解决方案JSONP

    1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP 2.什么是跨域? (1)默认浏览器为了安全问题,禁止了xmlhttprequest跨 ...

随机推荐

  1. smarty 判断变量是否为空

    {if $val.title!=""} 这里填写想要输出的内容即可 {/if}

  2. 【转】Mysql 根据时间戳按年月日分组统计

    create_time时间格式 SELECT DATE_FORMAT(create_time,'%Y%u') weeks,COUNT(id) COUNT FROM role GROUP BY week ...

  3. Linux06--Shell程序设计02 数据流重定向与管道

    包含3种数据流: •标准输入(stdin):代码为0,符号为<或<<; •标准输出(stdout):代码为1,符号为>或>>; •标准错误输出(stderr):代码 ...

  4. python学习day2(二)

    1.类与对象的关系 对于Python,一切事物都是对象,对象基于类创建 type是获取类的 dir是获取这个类里面的成员 2.int内部功能介绍 bit_length:返回表示当前数字占用的最少位数: ...

  5. JavaScript初学者应知的24条最佳实践(译)

    原文:24 JavaScript Best Practices for Beginners 译者:youngsterxyf (注:阅读原文的时候没有注意发布日期,觉得不错就翻译了,翻译到JSON.pa ...

  6. USB OTG学习

    1. 概要 OTG设备使用插头中的ID引脚来区分A/B Device,ID接地被称作为A-Device,为连接时候的USB Host,A-Device始终为总线提供电力,ID悬空被称作为B-Devic ...

  7. QT 线程池 + TCP 小试(一)线程池的简单实现

    *免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378 很久以前做过ACE + MFC/QT 的中轻量级线程池应用,大概就 ...

  8. Linux运维不可不知的性能监控和调试工具

    Linux运维不可不知的性能监控和调试工具 1 nagios Nagios是一个开源监控解决方案,我觉得他可以监控一切 ,可以看一下我以前的文章:NAGIOS 2 ps #用来查看程序的运行情况 ps ...

  9. OpenStreetMap(OSM) JMap Viewer(Java swing map)

    This article from:http://wiki.openstreetmap.org/wiki/JMapViewer JMapViewer is a java component which ...

  10. Linux网络设备驱动架構學習(三)

    Linux网络设备驱动架構學習(三) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...