同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
所谓同源是指,域名,协议,端口相同。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
浏览器是访问Internet的工具,也是客户端应用的宿主,它为客户端应用提供一个寄宿和运行的环境。而这里所说的应用,基本是指在浏览器中执行的客户端JavaScript程序。虽然是一种解释性的脚本语言,JavaScript其实是无比强大的,原则上来讲它可以做任何事。但是在能够在JavaScript脚本并不都是值得信赖的,所以浏览器必须对JavaScript的执行作相应的限制,这就是我们接下来着重介绍的“同源策略(Same Origin Policy)”。
同源策略是浏览器的一项最为基本同时也是必须遵守的安全策略,毫不夸张地说,浏览器的整个安全体系均建立在此之上。同源策略的存在,限制了“源”自A的脚本只能操作“同源”页面的DOM,“跨源”操作来源于B的页面将会被拒绝。所谓的“同源”,必须要求相应的URI在如下3个方面均是相同的。术语“源(Origin)”在中文表达中显得有点突兀,所以在接下来的内容中,我们更多地会采用“站点(Site)”或者“域(Domain)”这样的说法,在未作特别说明的情况下均与“源”表达相同的意思。
值得一提的是,对于一段JavaScript脚本来说,其“源”与它存储的地址无关,而取决于脚本被加载的页面。比如我们在某个页面中通过如下所示的<script>标签引用了来源于不同地方(“http://www.artech.com/”和“http://www.jinnan.me/”)的两个JavaScript脚本,它们均与当前页面同源。实际上接下来介绍的基于JSONP跨域资源共享就是利用了这个特性。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--配置手机端适应--> <meta name="viewport" content="width=device-width,initial-scale=1"> <!--配置css文件 核心CSS样式压缩文件--> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css"> <!--配置jQuery--> <script src="/static/bootstrap/jQuery.js"></script> <!--配置 核心Boot script JS压缩文件--> <script src="/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <h3>Idext</h3> <button class="get_service">洗剪吹</button> </body> <script> $(".get_service").on("click",function () { $.ajax({ url:"http://127.0.0.1:8006/service/", success:function (data) { alert(data) } }) }) </script> </html>
跨域问题分析
创建了2个端口号不一样,但是内容一样的djiango项目:
解决跨域问题
http://127.0.0.1:8006/ 端口(我是向8007跨域请求端)
前端页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--配置手机端适应--> <meta name="viewport" content="width=device-width,initial-scale=1"> <!--配置css文件 核心CSS样式压缩文件--> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css"> <!--配置jQuery--> <script src="/static/bootstrap/jQuery.js"></script> <!--配置 核心Boot script JS压缩文件--> <script src="/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <h3>Idext</h3> <button class="get_service">洗剪吹</button> </body> <script> // 跨域端口返回get_jsonp_data函数调用,将值以arg形式传进来。 function get_jsonp_function(arg) { alert(arg); console.log(typeof arg); var data = JSON.parse(arg); console.log(data); console.log(typeof data); } </script> <script> //点击向跨域端口发送一次service请求 function get_jsonp_data(url) { //创建一个script标签 var ele_svript = $("<script>"); //添加一个src属性 ele_svript.attr("src", url); ele_svript.attr("id", "jsonp"); // 添加到body文档树后面 $("body").append(ele_svript); //将多余的文档删除 $("#jsonp").remove() } </script> <script> $(".get_service").on("click", function () { //以另一端传过来的接口?callback= 自定义我们的函数名 get_jsonp_data("http://127.0.0.1:8007/service/?callback=get_jsonp_function"); }) </script> </html>
http://127.0.0.1:8007/ 端口(我是服务端)
view视图端
from django.shortcuts import render, HttpResponse import json # Create your views here. def index(request): return render(request, "index.html") def service(request): # 你需要跨域传的数据 info = {"name": "egon", "age": 34, "prive": 200} # 可以让跨区哪一步自己创建函数名,我只要给那边一个callback接口就行 func = request.GET.get("callback") return HttpResponse("%s(‘%s‘)" % (func, json.dumps(info),))
jsonp跨域终极解决版
请求端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--配置手机端适应--> <meta name="viewport" content="width=device-width,initial-scale=1"> <!--配置css文件 核心CSS样式压缩文件--> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css"> <!--配置jQuery--> <script src="/static/bootstrap/jQuery.js"></script> <!--配置 核心Boot script JS压缩文件--> <script src="/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <h3>Idext</h3> <button class="get_service">洗剪吹</button> </body> <script> // 跨域端口返回get_jsonp_data函数调用,将值以arg形式传进来。 function get_jsonp_function(arg) { alert(arg); console.log(typeof arg); var data = JSON.parse(arg); console.log(data); console.log(typeof data); } </script> <script> //终极模式 $(".get_service").on("click", function () { $.ajax({ url: "http://127.0.0.1:8007/service/", type: "get", dataType: "jsonp", //伪造ajax 基于script jsonpCallback:"get_jsonp_function", //服务端需要传并且客户端需要执行的函数, success: function (data) { // 数据也可以从success传进来并进行数据操作 } }) }) </script> </html>
服务端:
from django.shortcuts import render, HttpResponse import json # Create your views here. def index(request): return render(request, "index.html") def service(request): # 你需要跨域传的数据 info = {"name": "egon", "age": 34, "prive": 200} # 可以让跨区哪一步自己创建函数名,我只要给那边一个callback接口就行 func = request.GET.get("callback") return HttpResponse("%s(‘%s‘)" % (func, json.dumps(info),))
在服务端实现的方法:
思路:
在服务端的设置:
def service(request): # 你需要跨域传的数据 info = {"name": "egon", "age": 34, "prive": 200} response = HttpResponse(json.dumps(info)) # 解决跨域问题 * 表示允许所有的跨域请求 response["Access-Control-Allow-Origin"] = "*" # 在djiango 2.26版本中 经过我实验下面这个方法没用 # response[‘Access-Control-Allow-Origin‘] = "http://127.0.0.1:8006/" return response
跨域的应用:
<script> //示例 $(".get_service").on("click", function () { $.ajax({ url: "http://www.jxntv.cn/data/jmd-jxtv2.html", type: "get", dataType: "jsonp", //伪造ajax 基于script jsonp: "callbacks", //需要发送伪造的服务端的函数名称 jsonpCallback:"list" ,//服务端需要并执行的函数,服务端以经定好了list所以必须要以list接受 success: function (data) { console.log(data); //数据处理 var html=""; // each 是jquery中的循环 $.each(data.data,function (index,weekday) { console.log(weekday); // {week: "周日", list: Array(19)} // 我自定义了一个p标签,并且取出了字段中week的值。 html+=‘<p>‘+weekday.week+‘<p>‘; // 加等于的意思就是就是叠加。 $.each(weekday.list, function (j,show) { html+=‘<a href=‘+show.link+‘>‘+show.name+‘</a>‘ }) }); //找到body添加到后面 $("body").append(html) } }) }) </script>
原文:https://www.cnblogs.com/Rivend/p/11750162.html