ajax-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)
同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
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)的更多相关文章
- js中ajax如何解决跨域请求
js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...
- 原生JS实现Ajax及Ajax的跨域请求
前 言 如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...
- 原生JS实现Ajax的跨域请求
原生JS如何实现Ajax的跨域请求? 在解决这个问题之前,我们务必先清楚为什么我们要跨域请求,以及在什么情况下会跨域请求. 了解一下:“同源策略”,你就知道了: 同源策略限制从一个源加载的文档或脚本如 ...
- Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题
webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...
- 外部调用mvc的api方法时,如何解决跨域请求问题?
首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...
- SpringBoot解决跨域请求拦截
前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口. 同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种政策. 比如在域名https://www.baidu.co ...
- Ajax之跨域请求
一.引子 我现在开启了两个django项目,分别叫Demo1和Demo2,Demo1中有一个路径‘http://127.0.0.1:8000/index/’,对应的视图是index视图返回一个inde ...
- JSONP方法解决跨域请求
Ajax跨域请求的问题 跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子 <!D ...
- 利用Nginx轻松实现Ajax的跨域请求(前后端分离开发调试必备神技)
利用Nginx轻松实现浏览器中Ajax的跨域请求(前后端分离开发调试必备神技) 前言 为什么会出现跨域? 造成跨域问题的原因是因为浏览器受到同源策略的限制,也就是说js只能访问和操作自己域下的资源,不 ...
随机推荐
- iscroll.js的简单使用方法(总结)
iscroll.js的简单使用方法(总结) 一.总结 一句话总结:Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化. 最佳的HTML结构如下: <div id="wrap ...
- 【C#基本功 控件的用法】 Toolbar的用法
之前从事Labview编程,Labview是一门快速编程的语言,虽然快速,但作为一门语言他灵活性不够,有些方面也不是很给力,就比如 Toolbar labview就没有Toolbar的基础控件,虽然可 ...
- 五十 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门搜索
第三百七十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门 我的搜素简单实现原理我们可以用js来实现,首先用js获取到 ...
- 【Java】抽象类和接口
一.抽象类和抽象方法 1.什么是抽象类 普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法.普通方法.static方法.常量和变量等内容. 但是普通类中不能有抽象方法, ...
- windows钩子
(转自:http://wenku.baidu.com/view/5d41fdbec77da26925c5b08d.html) Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消 ...
- 记录下一次错误报http请求500,
1.请求控制层没问题,能请求到,如果缺少参数都会返回提示信息,但是请求参数都对了以后,居然报500,非常不解 找了好久,不知道哪里错了,最后经理提示是不是有可能,mapper.xml出错了,最后,我将 ...
- LeetCode OJ:Recover Binary Search Tree(恢复二叉搜索树)
Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...
- 【tensorflow:Google】三、tensorflow入门
[一]计算图模型 节点是计算,边是数据流, a = tf.constant( [1., 2.] )定义的是节点,节点有属性 a.graph 取得默认计算图 g1 = tf.get_default_gr ...
- 6.etc目录下重要文件和目录详解
1./etc/下的重要的配置文件 /etc(二进制软件包的 yum /rpm 安装的软件和所有系统管理所需要的配置文件和子目录.还有安装的服务的启动命令也放置在此处) /etc/sysconfig/n ...
- I-O流概念认知升级
在文件操作基础入门中,我们提到了流的 概念,这篇我们将更多的介绍流这个东西,以及C的I/O相关知识 现在,我们从C程序员最熟悉的printf函数开始学习I/O流. 我们对printf函数一直是很喜爱的 ...