同源策略

同源策略(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. selenium学习笔记(简单的元素定位)

    收拾一下心情开始新的一周工作 继续是selenium的学习.配置成功后 由于所有操作都是建立在页面元素基础上的.所以下来就是学习定位元素 首先是基础的定位.就使用博客园首页搜索框为例: 下面是代码: ...

  2. eclipse中修改工程的Android版本

    项目根目录下project.properties的记录项目中所需要的环境信息,比如Android的版本等 project.properties示例如下: [html] view plaincopy # ...

  3. ycsb两个阶段说明

     ycsb有几个目录需要注意下: bin: - 目录下有个可执行的ycsb文件,是个python脚本,是用户操作的命令行接口.ycsb主逻辑是:解析命令行.设置java环境,加载java-libs,封 ...

  4. 【scala】应用程序和App特性

    一.应用程序 要运行一个Scala对象,必须提供一个独立对象的名称.这个独立对象需要包含一个main方法,该方法接受一个Array[String]作为参数,结果类型为Unit. import Chec ...

  5. WCF基础:绑定(一)

    WCF中的终结点(ServiceEndpoint)包含有三要素:地址(EndpointAddress),绑定(Binding),契约描述(ContractDescription)三要素:其中绑定的在整 ...

  6. Agilent RF fundamentals (7) Oscillator characterization

    ---------------------------------------------------------------------------------------------------- ...

  7. python学习网址

    http://kuanghy.github.io/categories/#Python

  8. 利用selenium webdriver点击alert提示框

    在进行元素定位时常常遇到这样的alert框: 那么该如何定位并点击确定或取消按钮呢?stackoverflow上找到了这个问题的答案. OK, Show you the code: driver.fi ...

  9. 星火计划ROS机器人Spark

    星火计划ROS机器人Spark 1 http://wiki.ros.org/Robots/Spark 2 https://github.com/NXROBO/spark ---- Spark Spar ...

  10. [EMWIN]关于 GUI_GetPixelIndex 使用的问题

    在模拟器上和st单片机上使用以下代码: GUI_COLOR color0,color1; color0 = GUI_GetPixelIndex(rect.x1+1, rect.y0);color1 = ...