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只能访问和操作自己域下的资源,不 ...
随机推荐
- selenium学习笔记(简单的元素定位)
收拾一下心情开始新的一周工作 继续是selenium的学习.配置成功后 由于所有操作都是建立在页面元素基础上的.所以下来就是学习定位元素 首先是基础的定位.就使用博客园首页搜索框为例: 下面是代码: ...
- eclipse中修改工程的Android版本
项目根目录下project.properties的记录项目中所需要的环境信息,比如Android的版本等 project.properties示例如下: [html] view plaincopy # ...
- ycsb两个阶段说明
ycsb有几个目录需要注意下: bin: - 目录下有个可执行的ycsb文件,是个python脚本,是用户操作的命令行接口.ycsb主逻辑是:解析命令行.设置java环境,加载java-libs,封 ...
- 【scala】应用程序和App特性
一.应用程序 要运行一个Scala对象,必须提供一个独立对象的名称.这个独立对象需要包含一个main方法,该方法接受一个Array[String]作为参数,结果类型为Unit. import Chec ...
- WCF基础:绑定(一)
WCF中的终结点(ServiceEndpoint)包含有三要素:地址(EndpointAddress),绑定(Binding),契约描述(ContractDescription)三要素:其中绑定的在整 ...
- Agilent RF fundamentals (7) Oscillator characterization
---------------------------------------------------------------------------------------------------- ...
- python学习网址
http://kuanghy.github.io/categories/#Python
- 利用selenium webdriver点击alert提示框
在进行元素定位时常常遇到这样的alert框: 那么该如何定位并点击确定或取消按钮呢?stackoverflow上找到了这个问题的答案. OK, Show you the code: driver.fi ...
- 星火计划ROS机器人Spark
星火计划ROS机器人Spark 1 http://wiki.ros.org/Robots/Spark 2 https://github.com/NXROBO/spark ---- Spark Spar ...
- [EMWIN]关于 GUI_GetPixelIndex 使用的问题
在模拟器上和st单片机上使用以下代码: GUI_COLOR color0,color1; color0 = GUI_GetPixelIndex(rect.x1+1, rect.y0);color1 = ...