目录

  • 同源策略

    • 一个源的定义
    • 同源策略是什么
    • 举个例子
  • jQuery中getJSON方法
    • JSONP应用

1, 同源策略

1.1 一个源的定义

  • 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。

  • 举个例子:

  • 下表给出了相对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)

1.2 同源策略是什么

  • 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。

  • 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

1.2.1 不受同源策略限制的

  • 1 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。

  • 2 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的 <script src="..."></script>,<img>,<link>,<iframe> 等。

1.3 举个例子

  • 手写两个Django demo

1.3.1 demo1

  • urls.py
urlpatterns = [url(r'^abc/', views.abc),
]
  • views.py
def abc(request):return HttpResponse("rion")

1.3.2 demo2

  • urls.py
urlpatterns = [url(r'^xyz/', views.xyz),
]
  • views.py
def xyz(request):return render(request, "xyz.html")
  • xyz.html
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>$("#b1").click(function () {$.ajax({url: "http://127.0.0.1:8002/abc/",type: "get",success:function (res) {console.log(res);}})});
</script>
</body>
</html>
  • 现在,打开使用浏览器打开http://127.0.0.1:8000/xyz/,点击页面上的 '点我' 按钮,会在console页面发现错误信息如下:

  • 为什么报错呢?因为同源策略限制跨域发送ajax请求。

    • 应该会发现demo1项目其实已经接收到了请求并返回了响应,是浏览器对非同源请求返回的结果做了拦截。
    • 如果使用cdn方式引用的jQuery文件也是跨域的,它就可以使用。
    • 把xyz.html中的代码改一下:
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script src="http://127.0.0.1:8002/abc/"></script>
</body>
</html>
  • 现在,我们刷新一下页面,会出现如下错误提示:

  • 看来后端返回的响应已经被拿到了,只不过把rion当成了一个变量来使用,但是该页面上却没有定义一个名为rion的变量。所以出错了。

  • 那我定义一个rion变量还不行吗?

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>var rion = 100;
</script>
<script src="http://127.0.0.1:8002/abc/"></script>
</body>
</html>
  • 这次就不会报错了。

  • 我定义一个变量可以,那可不可以定义一个函数呢?

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>function rion() {console.log("选我不后悔!");}
</script>
<script src="http://127.0.0.1:8002/abc/"></script>
</body>
</html>
  • 同时把返回的响应也改一下:
def abc(request):return HttpResponse("rion()")
  • 此时,再次刷新页面,可以看到下面的结果。

  • 我返回的 rion(),页面上拿到这个响应之后直接执行了rion函数!

  • 那函数中可不可以传递参数呢?试一下!
  • demo2中的xyz.html

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>function rion(res) {console.log(res);}
</script>
<script src="http://127.0.0.1:8002/abc/"></script>
</body>
</html>
  • demo1中的视图函数:
def abc(request):res = {"code": 0, "data": ["SNIS-561", "SNIS-517", "SNIS-539"]}return HttpResponse("rion({})".format(json.dumps(res)))
  • 刷新页面查看效果:

  • 这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
  • 将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。
  • 但是我们更多时候是希望通过事件触发数据的获取,而不是像上面一样页面一刷新就执行了,这样很不灵活。
  • 其实这很好解决,我们可以通过javascript动态的创建script标签来实现。

  • demo2中的xyz.html

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>function rion(res) {console.log(res);}function addScriptTag(src){var scriptEle = document.createElement("script");$(scriptEle).attr("src", src);$("body").append(scriptEle);$(scriptEle).remove();}$("#b1").click(function () {addScriptTag("http://127.0.0.1:8002/abc/")})
</script>
</body>
</html>
  • 这样当我们点击b1按钮的时候,会在页面上插入一个script标签,然后从后端获取数据。
  • 为了实现更加灵活的调用,我们可以把客户端定义的回调函数的函数名传给服务端,服务端则会返回以该回调函数名,将获取的json数据传入这个函数完成回调。
  • demo2中的xyz.html
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>function rion(res) {console.log(res);}function addScriptTag(src) {var scriptEle = document.createElement("script");$(scriptEle).attr("src", src);$("body").append(scriptEle);$(scriptEle).remove();}$("#b1").click(function () {addScriptTag("http://127.0.0.1:8002/abc/?callback=rion")});
</script>
</body>
</html>
  • demo1中的views.py
def abc(request):res = {"code": 0, "data": ["SNIS-561", "SNIS-517", "SNIS-539"]}func = request.GET.get("callback")return HttpResponse("{}({})".format(func, json.dumps(res)))
  • 这样就能实现动态的调用了。

2, jQuery中getJSON方法

  • jQuery中有专门的方法实现jsonp。

  • demo2中的xyz.html

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>$("#b1").click(function () {$.getJSON("http://127.0.0.1:8002/abc/?callback=?", function (res) {console.log(res);})});
</script>
</body>
</html>
  • 要注意的是在url的后面必须要有一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个?是jQuery内部自动生成的一个回调函数名。

  • 但是如果我们想自己指定回调函数名,或者说服务上规定了回调函数名该怎么办呢?我们可以使用$.ajax方法来实现:

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>$("#b1").click(function () {$.ajax({url: "http://127.0.0.1:8002/abc/",dataType: "jsonp",jsonp: "callback",jsonpCallback: "rion2"})});function rion2(res) {console.log(res);}
</script>
</body>
</html>
  • 不过我们通常都会讲回调函数写在success回调中:
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>$("#b1").click(function () {$.ajax({url: "http://127.0.0.1:8002/abc/",dataType: "jsonp",success: function (res) {console.log(res);}})})
</script>
</body>
</html>

2.1 JSONP应用

// 跨域请求示例
$("#show-tv").click(function () {$.ajax({url: "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",dataType: 'jsonp',jsonp: 'callback',jsonpCallback: 'list',success: function (data) {var weekList = data.data;var $tvListEle = $(".tv-list");$.each(weekList, function (k, v) {var s1 = "<p>" + v.week + "列表</p>";$tvListEle.append(s1);$.each(v.list, function (k2, v2) {var s2 = "<p><a href='" + v2.link + "'>" + v2.name + "</a></p>";$tvListEle.append(s2)});$tvListEle.append("<hr>");})}})
});
  • 转自:https://www.cnblogs.com/liwenzhou/p/9513648.html

转载于:https://www.cnblogs.com/xiaoqshuo/p/10031729.html

Django - - 进阶 - - 同源策略和跨域解决方案相关推荐

  1. 同源策略和跨域解决方案

    同源策略 一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示 ...

  2. 浏览器的同源策略及跨域解决方案

    同源策略 一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示 ...

  3. 浏览器的同源策略与跨域问题的解决方案

    浏览器的同源策略与跨域问题的解决方案 参考文章: (1)浏览器的同源策略与跨域问题的解决方案 (2)https://www.cnblogs.com/yanggb/p/10735763.html 备忘一 ...

  4. 同源策略和跨域请求解决方案

    一.一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: ...

  5. websocket中发生数据丢失_tcp协议;websocket协议;同源策略和跨域

    tcp协议 为什么连接的时候是三次握手,关闭的时候却是四次握手? 答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文.其中ACK报文是用来应答的,SYN报 ...

  6. ajax背景、ajax对象、ajax状态、ajax与http、ajax请求数据接口、同步与异步、ajax请求XML数据、封装ajax函数、artTemplate简介、同源策略和跨域请求、JSONP

    AJAX简介: ajax背景: 1.AJAX(Asynchronous JavaScript And Xml)异步的 JavaScript 和 XML:ajax是浏览器提供的一套API,最早出现在谷歌 ...

  7. AJAX | 跨域与JSONP + 同源策略和跨域 + JSONP + 防抖和节流 + 案例 – 淘宝搜索

    目录 同源策略和跨域 同源策略 跨域 JSONP JSONP的实现原理 自己实现一个简单的JSONP JSONP的缺点 jQuery中的JSONP 自定义参数及回调函数名称 jQuery中JSONP的 ...

  8. 服务器安全:浏览器同源策略与跨域请求、XSS攻击原理及防御策略、如何防御CSRF攻击

    主要包括 浏览器同源策略与跨域请求 XSS攻击原理及防御策略 如何使用SpringSecurity防御CSRF攻击 CC/DDOS攻击与流量攻击 什么是SSL TLS HTTPS? 一.浏览器的同源策 ...

  9. 浏览器同源策略及跨域的解决方法

    浏览器同源策略及跨域的解决方法 参考文章: (1)浏览器同源策略及跨域的解决方法 (2)https://www.cnblogs.com/laixiangran/p/9064769.html 备忘一下.

最新文章

  1. 转:在RHEL5系统中搭建iSCSI存储服务器
  2. 前端:uniapp封装组件用法笔记
  3. 来一个可能防止恶意采集和爬虫的SH
  4. 在windows下,编译可访问https的libcurl静态库过程
  5. 【英语学习】【Daily English】U13 Holiday L01 I have been waiting for it for ages!
  6. (64)Verilog HDL多模块重复例化
  7. SQL ——利用窗口函数的T-SQL解决方案
  8. 负载均衡 > 用户指南 > 证书管理 > 证书要求
  9. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_14_常用的函数式接口_Predicate接口中的默认方法or和negate...
  10. 2022西电抗疫CTF个人赛
  11. win10杜比全景声评测_杜比全景声加持:Win10创意者更新空间音效设置扫盲
  12. 电路分析超详细思维导图
  13. 自动打卡php,使用腾讯云实现网易云自动打卡签到 | 小七呀w
  14. 【数据仓库】企业Spark案例--酒店数据分析实战
  15. 2022年的职场会是什么样子?
  16. 微信小程序 版本更新及调试方法
  17. 交大博士血泪自述:不是读博的料,别上博士这条船
  18. SIM900A(GSM模块)学习
  19. vue如何实现消息的无缝滚动
  20. Wolfram Mathematica学习笔记2

热门文章

  1. 【坐在马桶上看算法】排序总结:小哼买书
  2. MongoDB[mark]总忘记它们是干啥的
  3. 高可用性网络的简单配置方案(一)
  4. 单件模式(Singleton Pattern)
  5. BS-GX-018 基于SSM实现在校学生考试系统
  6. python作图一览
  7. 机器学习-线性回归与梯度下降
  8. javascript移动端 电子书 翻页效果
  9. 改变mysql数据库用户的权限
  10. Android 之窗口小部件详解--App Widget