同源策略

同源策略(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. iscroll.js的简单使用方法(总结)

    iscroll.js的简单使用方法(总结) 一.总结 一句话总结:Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化. 最佳的HTML结构如下: <div id="wrap ...

  2. 【C#基本功 控件的用法】 Toolbar的用法

    之前从事Labview编程,Labview是一门快速编程的语言,虽然快速,但作为一门语言他灵活性不够,有些方面也不是很给力,就比如 Toolbar labview就没有Toolbar的基础控件,虽然可 ...

  3. 五十 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门搜索

    第三百七十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门 我的搜素简单实现原理我们可以用js来实现,首先用js获取到 ...

  4. 【Java】抽象类和接口

    一.抽象类和抽象方法 1.什么是抽象类 普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法.普通方法.static方法.常量和变量等内容. 但是普通类中不能有抽象方法, ...

  5. windows钩​子​

    (转自:http://wenku.baidu.com/view/5d41fdbec77da26925c5b08d.html) Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消 ...

  6. 记录下一次错误报http请求500,

    1.请求控制层没问题,能请求到,如果缺少参数都会返回提示信息,但是请求参数都对了以后,居然报500,非常不解 找了好久,不知道哪里错了,最后经理提示是不是有可能,mapper.xml出错了,最后,我将 ...

  7. LeetCode OJ:Recover Binary Search Tree(恢复二叉搜索树)

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  8. 【tensorflow:Google】三、tensorflow入门

    [一]计算图模型 节点是计算,边是数据流, a = tf.constant( [1., 2.] )定义的是节点,节点有属性 a.graph 取得默认计算图 g1 = tf.get_default_gr ...

  9. 6.etc目录下重要文件和目录详解

    1./etc/下的重要的配置文件 /etc(二进制软件包的 yum /rpm 安装的软件和所有系统管理所需要的配置文件和子目录.还有安装的服务的启动命令也放置在此处) /etc/sysconfig/n ...

  10. I-O流概念认知升级

    在文件操作基础入门中,我们提到了流的 概念,这篇我们将更多的介绍流这个东西,以及C的I/O相关知识 现在,我们从C程序员最熟悉的printf函数开始学习I/O流. 我们对printf函数一直是很喜爱的 ...