JavaScript JSONP跨域解决方案
2018-01-06 本文已影响64人
HelloJames
1. 什么是JSONP
首先提一下JSON这个概念,JSON是一种轻量级的数据传输格式,被广泛应用于当前Web应用中。JSON格式数据的编码和解析基本在所有主流语言中都被实现,所以现在大部分前后端分离的架构都以JSON格式进行数据的传输。
那么JSONP是什么呢?
首先抛出浏览器同源策略这个概念,为了保证用户访问的安全,现代浏览器使用了同源策略,即不允许访问非同源的页面。在ajax中,不允许请求非同源的URL就可以了,比如www.a.com下的一个页面,其中的ajax请求是不允许访问的.
所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来
百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于
哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
2. JSONP原理
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
**3. JSONP具体实现(后台: python, tornado)****
- 前端代码
<script type="text/javascript">
function jsonpHandler(data){
console.log(data);
}
$.ajax({
type : "get",
async: false,
url : "http://10.149.6.154:8000/api",
dataType: "jsonp",
jsonp:"callback", //请求后台的参数名, 发送请求时将会用到
jsonpCallback: "jsonpHandler",//要执行的回调函数, 请求成功后的处理函数
});
</script>
- 后台代码(tornado)
-------------------------------
<urls.py>
-------------------------------
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.websocket
import views.index
url_pattens = [
tornado.web.URLSpec(r'^/api$', views.index.ApiHandler, name='api'), # 此段代码仅供后台人员参考
]
-------------------------------
<view.py>
-------------------------------
import json
from core.handler import base
class ApiHandler(base.BaseHandler):
def get(self, *args, **kwargs):
callback_name = self.get_argument('callback', "jsonpHandler") // 获取参数callback的值, 对应于前端的jsonp的值
data = {'username': 'name', 'password': 'passwd'}
res = json.dumps(data)
self.set_header('Content-Type', 'application/javascript') // 注意返回的content-type类型为: application/javascript
self.write("%s(%s)" % (callback_name, res)) // 注意返回的内容的格式: 回调函数名(要返回的数据), 如此处的结果为: jsonphandler({'username': '