同源策略和跨域解决方案
同源策略
一个源的定义
同源策略和跨域解决方案
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
举个例子:
下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例:
URL | 结果 | 原因 |
---|---|---|
http://a.xyz.com/dir2/other.html |
成功 | |
http://a.xyz.com/dir/inner/another.html |
成功 | |
https://a.xyz.com/secure.html |
失败 | 不同协议 ( https和http ) |
http://a.xyz.com:81/dir/etc.html |
失败 | 不同端口 ( 81和80) |
http://a.opq.com/dir/other.html |
失败 | 不同域名 ( xyz和opq) |
同源策略是什么
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
不受同源策略限制的
1. 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2. 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。
举例:
demo1
手写两个项目
url.py
from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^lulu/$',views.lulu) ]
views.py
def lulu(request): res = {"code": 0, "haha": [1, 2, 3]} data_str = json.dumps(res) return HttpResponse("luhan({})".format(data_str))
demo2
url.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^haha/$',views.haha) ]
views.py
def haha(request): return render(request, "haha.html")
html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <button id="a1">点我</button> <script> {#var hahaha = "sbbs";#} {#console.log(hahaha)#} function luhan(res) { console.log(res) } </script> <script src="http://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> {#点击点我获取数据#} <script> $("#a1").click(function () { var scriptEle = document.createElement("script"); $(scriptEle).attr("src","http://127.0.0.1:8010/lulu/"); $("body").append(scriptEle); $(scriptEle).remove(); }) </script> {#刷新页面直接获取数据#} {#<script src="http://127.0.0.1:8010/lulu/"></script>#} </body> </html>
传参数也可以实现
简单使用方法:
2. jsonp(json padding) 1. jsonp的原理是什么? 利用script标签绕过同源策略的限制,拿到数据 alex('{name:"alex", "age": 18}') 2. jQuery封装的jsonp 1. 简单的getJSON() $.getJSON("http://127.0.0.1:8010/abc/?callback=?",function(){}) 2. 进阶的用法 $.ajax({ url: "http://127.0.0.1:8010/abc/", dataType: "jsonp", jsonp: "callback", jsonpCallback: "回调函数名", success:function(res){ // 拿到响应的数据之后要做的事儿 } })
应用举例,江西电视台:给定一个特定的url,解析数据:
http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>about_jsonp2 xyz</title> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"> </head> <body> <button id="b1">点我</button> <div class="tv-list"> </div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> $("#b1").click(function () { $.ajax({ url: "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403", dataType: "jsonp", // 指定此次请求是jsonp形式 jsonpCallback: "list", success:function (res) { console.log(res.data); $.each(res.data, function (k1, v1) { var divEle = document.createElement("div"); divEle.innerText = v1.week; $(".tv-list").append(divEle); // 继续循环list $.each(v1.list, function (k2, v2) { var pEle = ` <p><a href="${v2.link}">${v2.name}</a></p> `; $(divEle).append(pEle); }); }) } }) }) </script> </body> </html>
总结
1. 同源策略 1. 什么叫同源策略 1. 一个源的定义 协议+IP(域名)+端口一致,就是同一个源。 2. 同源策略限制了脚本(js)跨网站发请求,能发请求但是拿不到响应 3. 不受同源策略限制的 1. a标签、重定向、form表单的提交 2. script、link标签等不受同源策略的限制,可以引用其他站点内容
2. jsonp(json padding) 1. jsonp的原理是什么? 利用script标签绕过同源策略的限制,拿到数据 alex('{name:"alex", "age": 18}') 2. jQuery封装的jsonp 1. 简单的getJSON() $.getJSON("http://127.0.0.1:8010/abc/?callback=?",function(){}) 2. 进阶的用法 $.ajax({ url: "http://127.0.0.1:8010/abc/", dataType: "jsonp", jsonp: "callback", jsonpCallback: "回调函数名", success:function(res){ // 拿到响应的数据之后要做的事儿 } })