JSONP跨域访问
来源:互联网 发布:外文电子期刊数据库 编辑:程序博客网 时间:2024/05/21 08:54
前言
昨天在写一个只使用原生js的一个todolist小玩意,然后想给它添加个当地天气的小功能,
没想到引发我的一堆基础不牢靠
ajax
首先,我是想使用ajax的GET方法获取天气api的数据(以前使用jq获取过),可是怎么也获取不了,
并且request.status === 0
,此时的我很懵逼,一直看过404,200,304,500啥的,就没看过0.
后来google一下,发现是跨域问题。以前也听说过跨域,但一直没去深究,并且以前使用ajax也是调用本地数据,
所以一直都不怎么了解。先来看看什么是跨域。。
- 概念
只要协议、域名、端口有任何一个不同,都被当作是不同的域。
对于端口和协议的不同,只能通过后台来解决。
- 具体来说
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://70.32.92.74/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同一域名,不同二级域名(同上)不允许(cookie这种情况下也不允许访问)http://www.cnblogs.com/a.js http://www.a.com/b.js不同域名不允许所以说,一旦跨域了,就无法使用ajax来请求其他网站提供的数据(如天气api,快递api)。
因为以前使用了jq的getJSON
,因为它已经封装好,所以没有意识到跨域问题
具体怎么使用jq跨域,看我以前写的一个天气预报小demo
为何浏览器不支持跨域访问
因为浏览器实现的同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,所以AJAX是不允许跨域的
举个例子,如果我在我的页面上使用<iframe>
标签嵌一个银行页面,而你在我当前页面登陆那个嵌套的银行页面,在没有同源策略限制下,
我就可以通过js读取到你输入的银行密码和登录名,这样你就gg了。
JSONP
虽然ajax不支持跨域访问,但是像<script>
,<link>
,<img>
,<iframe>
这些标签是允许跨域的,
你应该有使用过<link>
调用过外部的css,或者<script>
调用过外部的js文件。
所以JSONP就利用了这点来实现跨域访问
但是我不想使用jq,毕竟jq能解决的js爸爸也肯定能解决,所以我就来了解原生的jsonp
- jsonp介绍
全称 JSON with Padding,用于解决AJAX跨域问题的一种方案
- jsonp原理
利用<script>
标签获取到api数据,再把数据传给回调函数进行操作
<script type="text/javascript"> function dosomething(jsondata){ } </script> <script src="http://a.com/data.php?callback=dosomething"></script>
- JSONP小贴士
js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。
所以JSONP是需要服务器端的页面进行相应的配合的。
例如<script src="http://a.com/data.php?callback=dosomething&name=芝士君&sex=man></script>
我们传入的name
和sex
,服务器接收到该数值,要做出相应的反应,回馈相应数据
- JSONP优缺点
优: 兼容性非常好,其原理决定了即便在非常古老的浏览器上也能够很好的被实现。
缺: 只能 GET 不能 POST,存在xss脚本注入的安全隐患
结语
实现JSONP的人真机智,感觉就像那些钻法律空子的人。hhh贬义的比喻褒义地夸