同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

url http ip port paht ? 数据
  if 协议 IP PORT相同,同源

一,问题描述

 django 创建2个项目
项目一,开启一个send_ajax请求 http://127.0.0.1:8000
访问正常 项目二,没有send_ajax请求 http://127.0.0.1:8010
那么这时候如果你通过ajax访问的 url:http://127.0.0.1:8000/send_ajax
浏览器会报错,内容是已拦截跨域请求,同源策略禁止读取位于http://127.0.0.1:8000/send_ajax远程资源,原因:cors头缺少 ‘Access-Control-Allow-Origin’

1.1 思考

jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

 跨域请求:
ajax请求一定会被拦截 核心任务:跨域请求的是数据,数据,数据 通过引入jquery cdn 可以跨域 我们想 是不是script标签不会被拦截呢?
<script src=" https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>

1.2跨域请求的演变

 项目一 views
import json
def send_ajax(request):
return HttpResponse("yuan") # 第一次返回字符串
return HttpResponse("yuan()") # 第二次返回函数字符串
return HttpResponse("yuan('yuan')") # 第三次返回函数参数字符串
s='hello world'
return HttpResponse("yuan('%s')"%s) # 第四次返回函数字符串数据 s={"name":"egon","age":122}
return HttpResponse("%s('%s')"%(func_name,json.dumps(s))) # 第五次返回函数json字符串 项目二 html
第一次字符串,你要是知道数据是什么还请求干什么?所以这里只是个引子,告诉你可以这样做
<script>yuan</script>
<script src="http://127.0.0.1:8000/send_ajax"></script> 第二次函数字符串
<script>function yuan(){alert(123)}</script>
<script src="http://127.0.0.1:8000/send_ajax"></script> 第三次返回函数参数字符串
<script>function yuan(arg){alert(arg)}</script>
<script src="http://127.0.0.1:8000/send_ajax"></script> 第四次返回函数字符串数据(数据也是字符串)
<script>function yuan(arg){alert(arg)}</script>
<script src="http://127.0.0.1:8000/send_ajax"></script> 第五次返回函数json字符串
<script>function yuan(arg){alert(Json.parse(arg))}</script>
<script src="http://127.0.0.1:8000/send_ajax"></script>

1.3问题

 我不能硬生生的将<script src="http://127.0.0.1:8000/send_ajax"></script>写在html里面,我需要动态创建下面的函数

我们通过触发点击事件函数创建

 <script>
function yuan(arg) {
console.log(arg);
console.log(JSON.parse(arg));
}
</script> <script>
$(".send_ajax").click(function () {
kuayu_request("http://127.0.0.1:8000/send_ajax/")
});
function kuayu_request(url) {
var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
$script.attr("src",url);
$("body").append($script);
$("body script:last").remove();
}
</script>

1.4 问题

 1 问题函数名字是不是可以通过请求传送到后端呢?应该是同步的,可否通过回调函数?

  可以通过发送请求的时候带着数据,数据包含你的函数名称,这样传到后端,再让后端返回你这个函数和数据,就可以执行了

 项目二 html
<script>
$(".send_ajax").click(function () {
kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar")
});
function kuayu_request(url) {
var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
$script.attr("src",url);
$("body").append($script);
$("body script:last").remove();
}
</script> 项目一 views
def send_ajax(request):
func_name = request.GET.get('callback')
s = 'hello'
return HttpResponse("%s('%s')"%(func_name,json.dump(s)))

之前都是引子,下面才是真正的用法。。

ajax的跨域请求写法

 <script>

     $(".send_ajax").click(function () {

         $.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
success:function (data) {
alert(data)
},
// 跨域请求 <script> 告诉服务器我要什么类型的数据contenttype是告诉服务器我是什么类型数据
dataType:"jsonp",
jsonp: 'callbacks', //?callbacks=SayHi 相当于这个,问题就是在于前后端的函数名要相同
jsonpCallback:"SayHi"
}) }); function SayHi(arg) {
console.log("hello",arg)
}
</script> {#// ==========================================基于jquery的JSONP的实现3 (推荐)#} <script> $(".send_ajax").click(function () { $.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
dataType:"jsonp", // 跨域请求 <script>
// callbacks=? ?就是随机字符串了,后端传回来运行的就是success函数,也就是funciton 函数参数是数据
jsonp: 'callbacks',
success:function (data) {
console.log(data)
}
}) }); </script>

jsonp的所有实现和应用例子

项目一的views.py

 import json
def send_ajax(request):
s={"name":"egon","age":122}
return HttpResponse("list('%s')"%json.dumps(s))

项目二的index.html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
</head>
<body>
<h1>项目2的首页</h1>
<button class="send_ajax">send_ajax</button> {#// ==========================================基于JS的JSONP的实现#}
<script>
function bar(arg) {
console.log(arg);
console.log(JSON.parse(arg));
}
</script> <script> $(".send_ajax").click(function () {
kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar") // 回调函数
});
// 创建script添加scr属性,获取数据
function kuayu_request(url) {
var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
$script.attr("src",url);
$("body").append($script);
$("body script:last").remove();
} </script> <hr> {#// ==========================================基于jquery的JSONP的实现1#} <script> $(".send_ajax").click(function () {
// getJSON帮助我们创建了script标签和src属性 ,还有个参数,data= 可以写入一些给后端的字符串
// 匿名函数,函数会有getJSON创建随机字符串也就是callbacks=?的问好的值,函数参数的data是数据
$.getJSON("http://127.0.0.1:8000/send_ajax/?callbacks=?",function (data) {
console.log(data)
})
}) </script> {#// ==========================================基于jquery的JSONP的实现2#} <script> $(".send_ajax").click(function () { $.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
success:function (data) {
alert(data)
},
// 跨域请求 <script> 告诉服务器我要什么类型的数据contenttype是告诉服务器我是什么类型数据
dataType:"jsonp",
jsonp: 'callbacks', //?callbacks=SayHi 相当于这个,问题就是在于前后端的函数名要相同
jsonpCallback:"SayHi"
}) }); function SayHi(arg) {
console.log("hello",arg)
}
</script> {#// ==========================================基于jquery的JSONP的实现3 (推荐)#} <script> $(".send_ajax").click(function () { $.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
dataType:"jsonp", // 跨域请求 <script>
// callbacks=? ?就是随机字符串了,后端传回来运行的就是success函数,也就是funciton 函数参数是数据
jsonp: 'callbacks',
success:function (data) {
console.log(data)
}
}) }); </script> {#// =========================================应用#} <script> $(".send_ajax").click(function () { $.ajax({
url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"list"
}) }); function list(shuju) {
console.log(shuju.data); // {data: Array(7)}
var data=shuju.data; // [{},{},{},......] $.each(data,function (i,weekend) {
//console.log(weekend); // {week: "周日", list: Array(19)}
console.log(weekend.list); // {week: "周日", list: Array(19)}
var week= weekend.week;
$("body").append("<div>"+week+"</div>"); $.each(weekend.list,function (i,show) {
console.log(show); // {time: "", name: "《都市现场》90分钟直播版块", link: "http://www.jxntv.cn/live/jxtv2.shtml"} var $a=$("<a>"); // <a></a>
$a.html(show.name);
$a.attr("href",show.link); $("body").append('<p>');
$("body").append($a);
$("body").append('</p>'); }) }) }
</script>
</body>
</html>

 注意 JSONP一定是GET请求

CORS跨域资源共享(CORS,Cross-Origin Resource Sharing)

其本质是设置响应头,使得浏览器允许跨域请求。

项目一要访问项目二的视图,项目二的ajax请求代码如下

 <h1>项目2的首页cors</h1>

 <button class="send_ajax">send_ajax</button>

 <script>

     $(".send_ajax").click(function () {

         $.ajax({
// 这里我访问s1的的send_ajax
url:"http://127.0.0.1:8000/send_ajax/",
type:'GET', // head get post put delete
success:function (data) {
console.log(data);
console.log('')
}
}) })
</script>

项目二通过路由找到视图返回数据的代码如下

 import json
def send_ajax(request):
# 授权的origin可以用*代替所有,methods可以多个,用逗号分开,简单的放一起,复杂放一起
if request.method == "OPTIONS": # 预检
response = HttpResponse() response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011"
response["Access-Control-Allow-Methods"] = "PUT" return response elif request.method == "PUT": # 复杂请求,需要通过预检 put delete
s = {"name": "egon", "age": 122} response = HttpResponse(json.dumps(s))
response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011" return response elif request.method == 'GET': # 简单强求 head get post
s = {"name": "egon", "age": 122} response = HttpResponse(json.dumps(s))
response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011" return response

流程:

项目二向项目一发送请求,项目一根据请求匹配路由规则,找到视图,视图首先返回给浏览器,如果没有cors就会被浏览器拦截,有了cors设置,浏览器就不会拦截cors设置的请求方式,最终

返回给项目一的数据,上述例子中,复杂请求(put,delete)先走预检,添加put请求,和允许访问的url,返回给浏览器,浏览器得到后在向服务器发送put请求,拿到数据,最后给项目一。

ajax-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)的更多相关文章

  1. js中ajax如何解决跨域请求

    js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...

  2. 原生JS实现Ajax及Ajax的跨域请求

      前  言          如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...

  3. 原生JS实现Ajax的跨域请求

    原生JS如何实现Ajax的跨域请求? 在解决这个问题之前,我们务必先清楚为什么我们要跨域请求,以及在什么情况下会跨域请求. 了解一下:“同源策略”,你就知道了: 同源策略限制从一个源加载的文档或脚本如 ...

  4. Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题

        webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...

  5. 外部调用mvc的api方法时,如何解决跨域请求问题?

    首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...

  6. SpringBoot解决跨域请求拦截

    前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口. 同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种政策. 比如在域名https://www.baidu.co ...

  7. Ajax之跨域请求

    一.引子 我现在开启了两个django项目,分别叫Demo1和Demo2,Demo1中有一个路径‘http://127.0.0.1:8000/index/’,对应的视图是index视图返回一个inde ...

  8. JSONP方法解决跨域请求

    Ajax跨域请求的问题 跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子 <!D ...

  9. 利用Nginx轻松实现Ajax的跨域请求(前后端分离开发调试必备神技)

    利用Nginx轻松实现浏览器中Ajax的跨域请求(前后端分离开发调试必备神技) 前言 为什么会出现跨域? 造成跨域问题的原因是因为浏览器受到同源策略的限制,也就是说js只能访问和操作自己域下的资源,不 ...

随机推荐

  1. scala LocalDateTime String 转换

    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime ti ...

  2. DP问题如何确定状态

    DP问题如何确定状态 一.dp实质 动态规划的实质就是通过小规模的同类型的问题来解决题目的问题. 所以有一个dp数组来储存所有小规模问题的解. 所以确定状态也就是缩小问题规模. 我们求解问题的一般规律 ...

  3. git下载别人的代码

    1. 打开别人github上的源码地址,点击Clone or download 2. 拷贝链接 3. 通过git clone URL来下载 此外,还可以通过pwd来查看当前目录的路径,一般都是下载到当 ...

  4. spring boot配置德鲁伊

    1.引入相关依赖,全部依赖是上一篇spring boot+mybatis依赖的基础上,再加上下边的依赖,如下: <!-- Druid数据库连接池组件 --> <dependency& ...

  5. urllib2打开URL(含中文)的问题

    import urllib2 url = u"http://www.baidu.com/wd=测试" urllib2.urlopen(url.encode('utf-8')).re ...

  6. Node.js小白开路(一)-- fs篇

    文件操作在我们的日常功能模块之中是十分的常见的内容,nodeJS也不例外的为我们提供了之一操作内容,当时在我们了解文件操作的之前我们先来了解一下链接. 连接可以理解成为一个纸箱相关文件内容的地址,其主 ...

  7. 012——VUE中todos示例讲解class中应用表达式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Oracle11g数据库监听配置

    (转自:http://blog.sina.com.cn/s/blog_6908928501018057.html) 经验告诉我:最好把数据库的SID和数据库全局名称分开,免得配置时混了,如果要配置服务 ...

  9. L127

    Biggest Studies on Aspirin Show Risks Outweigh Benefits for Many People Doctors have long recommende ...

  10. 用同步的方式执行jQuery异步动画

    在编写jQuery动画时,通过回调函数进行动画队列的编排,但当回调过多,往往会出现这样的代码: $(".box1").fadeIn(1000,function(){ $(" ...