美文网首页
沉淀 | 从同源策略、跨域请求到JSONP

沉淀 | 从同源策略、跨域请求到JSONP

作者: 8c9c47c26245 | 来源:发表于2016-05-09 09:28 被阅读151次

JavaScript有多大权限?

JavaScript只能嵌在页面中、被浏览器执行。JavaScript是依赖于页面而存在的。可以说,JavaScript是网页的一部分。
JavaScript在Web浏览器这个宿主环境中,通过浏览器提供的宿主对象和API啥的、有很多的权限:

  • 第一,对Html文档的操作权限
    在文档中,用<script>表现的src属性引入一个js文件的时候,就已经把该文档的访问和操作权限、都赋予了js脚本。也就是说,
    JavaScript对宿主文档有全权控制权,通过浏览器提供的document对象。

JavaScript还可以跨文档访问,当然、必须是在同一个浏览器中的:比如页面<iframe>中内嵌的文档、同一浏览器中其他标签的文档。

  • 第二,向服务器发送Ajax请求
    通过浏览器提供的 XMLHtttpRequest类实例,JavaScript可以向服务端发送HTTP请求、并在回调函数中异步的得到服务器的响应。XMLHttpRequest类对象是W3C的规范规范,且浏览器支持得很好。

  • 第三,访问其他系统功能
    通过浏览器提供的接口,JavaScript还可以访问本地存储、获取用户地理位置信息、用户操作记录等。

浏览器对JavaScript的限制

浏览器之于JavaScript,就像操作系统至于应用程序。操作系统当然可以控制应用程序的权限,出于安全等因素的考虑。
浏览器也可以对JavaScript的行为进行限制,其中的一种限制就是“同源策略”。

同源策略

“同源”指的是协议、主机名和端口的相同。我觉得一般意义上,这三项相同的文档就代表是同一个Web应用;而任何一项不同就代表不同的Web应用了。

同源策略要求两点:
1)JavaScript只能操作和访问与宿主文档同源的文档。
宿主文档值得是引入JavaScript的那个文档,当然、是通过<script>的src属性。

2)XMLHttpRequest对象只能向同源的服务器发送请求。

XMLHttpRequest是浏览器提供的内置类,可以通过它向服务端发送Http请求、它是实现Ajax的最简单方法(当然不是唯一的)。
发送跨域请求一般会返回这样的错误:

XMLHttpRequest cannot load http://google.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.jsbin.io' is therefore not allowed access. 

跨域请求

这样做就可以避免不同的Web应用之间互相操作,进而避免一些非法操作。但与此同时,有些合法的“跨域操作”也被限制住了。那现在只关注“我想发送跨域的Ajax”这种情况——在现有浏览器框架下,可以怎样实现?

第一,跨域资源共享

CROS是Cross-Origin-Resource-Share的缩写,跨域资源共享。

在HTTP响应的Head中指定:Access-Control-Allow-Origin 来扩展http

Access-Control-Allow-Origin: 由服务器指定跨域请求白名单。如果它的值设为 *
,则表示谁都可以用

Access-Control-Allow-Origin: *

没错,在产品环境中,没人会用 *,而是会显示指定白名单:


Access-Control-Allow-Origin: http://run.jsbin.io

发送A请求的时候,浏览器检查A响应中的head,如果acao允许本文档访问,则通过请求;否则不返回response

这样Httprequest消息就不受同源限制了。

我觉得跨域资源共享是实现跨域请求的简单、标准方法,但这需要浏览器的支持 —— 浏览器必须识别响应中的Access-Control-Allow-Origin并据此判断JavaScript是否可以得到响应。

很可惜、有些旧的浏览器不支持“跨域资源共享”。

第二、JSONP可以绕过浏览器的限制、发送跨域请求

克服该限制的另一个方法是在页面中插入动态<script>元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。

JSONP原理

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

此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

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

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

如何实现

下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数。

<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
<script type="text/javascript">  
    function jsonpCallback(result) {  
        //alert(result);  
        for(var i in result) {  
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
        }  
    }  
    var JSONP=document.createElement("script");  
    JSONP.type="text/javascript";  
    JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  
    document.getElementsByTagName("head")[0].appendChild(JSONP);  
</script>  

服务端PHP代码 (services.php):

//服务端返回JSON数据  
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);  
$result=json_encode($arr);  

//动态执行回调函数  
$callback=$_GET['callback'];  
echo $callback."($result)";  

注意到,JSONP说的是一种协议

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

服务端返回的是“JSNOP”的文档格式,客户端也要用特殊的方式去获取数据;协议的意思就是要两者配合完成的。

主要提示

JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。

第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。

JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。

相关文章

  • 做demo和学习过程当中遇到的一些问题,收集的博文

    轻松搞定JSONP跨域请求--->关键字: 跨域, 同源策略, JSONP原理 git拉取远程分支到本地 git ...

  • 沉淀 | 从同源策略、跨域请求到JSONP

    JavaScript有多大权限? JavaScript只能嵌在页面中、被浏览器执行。JavaScript是依赖于页...

  • jsonp

    jsonp的跨域原理解析 背景: 由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp就是为了解...

  • Jsonp 跨域原理

    Jsonp 跨域原理。(摘选) 浏览器的同源策略把跨域请求都禁止了,但是页面中的 标签是例外,不受同源策略限...

  • AJAX和JSONP请求

    同源策略:端口 域名 协议相同 跨域解决CORS代理请求方式jsonp JSONP流程:动态创建script标签,...

  • Ajax跨域 —— Jsonp

    同源策略 同源/同域即域名、协议、端口号相同 JSONP(JSON with Padding) 是一种跨域请求方式...

  • Jsonp的实现原理

    1. Jsonp Jsonp: 主要是用来获取跨域的请求,由于同源策略的限制,我们不能获取跨域的资源 2. Jso...

  • 前端基础(问答23)

    keywords: 同源策略、跨域、jsonp。 什么是同源策略(same origin policy) 同源:协...

  • jsonp

    参考:轻松搞定JSONP跨域请求参考:JavaScript 跨域总结与解决办法要理解跨域,先要了解一下“同源策略”...

  • 跨域的方式及解决

    参考:同源策略 JSONP跨域实现和解决方式 它的工作原理在于script标签不受同源策略限制,并且请求得到scr...

网友评论

      本文标题:沉淀 | 从同源策略、跨域请求到JSONP

      本文链接:https://www.haomeiwen.com/subject/pnferttx.html