同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
同源
域名、协议、端口相同,也就是在同一个域里。
非同源受到的限制
- cookie不能读取 (如我在自己的站点无法读取博客园用户的cookie)
- dom无法获得
- ajax请求不能发送
什么是浏览器跨域
例如:
一个域的页面去请求另一个域的资源;
A域的页面去请求B域的资源。
如何跨域
这里只说Jsonp跨域和CORS跨域两种机制
参考:
http://www.cnblogs.com/bigtreei/p/8431673.html#_label6
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
Jsonp实现跨域
JSONP的基本原理
动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。
这样一来,这种跨域方式就与ajax XmlHttpRequest协议无关了。
JSONP即JSON with Padding
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。
如果要进行跨域请求, 我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象,这种跨域的通讯方式称为JSONP。
JSON 是一种数据格式
JSONP 是一种数据调用的方式
Jsonp的执行过程
首先在客户端注册一个callback (如:'TestJsonpCallback'), 然后把callback的名字(如:testjsonpcallback)传给服务器。
注意:
服务端得到callback的数值后,要用TestJsonpCallback(......)把将要输出的json内容包括起来,此时,服务器生成 json 数据才能被客户端正确接收。
然后以 javascript 语法的方式,生成一个function, function 名字就是传递上来的参数 'callback'的值 TestJsonpCallback.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数, 传入到了客户端预先定义好的 callback 函数.
实例展示
访问端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/jquery.js"></script> </head> <body> <h1>index</h1> <p><input type="button" onclick="Jsonp1();" value='提交'/></p> <p><input type="button" onclick="Jsonp2();" value='提交'/></p> <script> function Jsonp1() { var tag = document.createElement('script'); tag.src = "http://127.0.0.1:8888/data/"; document.head.appendChild(tag); document.head.removeChild(tag); } function asdasdasd(data) { console.log(data) } function Jsonp2() { $.ajax({ url: "http://127.0.0.1:8888/data/", type: 'GET', dataType: 'JSONP', jsonp: 'call', jsonpCallback: 'asdasdasd', } ) } </script> </body> </html>
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^jsonp/', views.index), ]
from django.shortcuts import render def index(request): return render(request,'index.html')
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
被访问端
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^data/', views.data), ]
from django.shortcuts import render, HttpResponse def data(request): callback = request.GET.get('call') return HttpResponse('%s("数据")' % callback)
用访问端访问目标主机,目标主机能成功返回 "函数名("参数")" , 表示成功跨域.
CORS实现跨域请求
参见: http://www.cnblogs.com/bigtreei/p/8431673.html#_label7