ajax跨域资源共享
一、同域发送数据
略
二、跨域发送数据
1、存在的问题
1、什么是同源策略
同源策略阻止从一个域名上加载的脚本获取或操作另一个域名上的文档属性。也就是说,受到请求的 URL 的域名必须与当前 Web 页面的域名相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。
2、ajax跨域发送数据受到浏览器同源策略的影响,当ajax向其他域名发送数据时,其他域名服务器正常处理该请求并且返回数据给ajax,但是客户端浏览器会检测到该数据是跨域请求的数据,然后就组织该数据的接收(即ajax跨域发送数据,服务端正常返回数据,客户端判断跨域发送阻止数据接受)。
2、解决方法原理
1、原理1:前端发送数据虽然ajax受同源策略限制。但是前端<script>、<img>、<iframe>等节点元素发送数据不受同源策略限制(凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>)。ajax可以仿照前端script节点元素发送数据从而绕过浏览器同源策略限制,即jsonp方法(绕过策略,后们进入)。
2、原理2:前端向异域名发送ajax数据之所以不能接受到数据是由于收浏览器的同源策略影响,所以我们可以通过代理的方式来让代理帮我们发送数据到服务端,并且让代理帮我们接收服务端数据,因为代理上接受和发送数据不是通过浏览器进行发送接受的,所以不会受同源策略的影响。比如说python中的requests模块是专门仿造浏览器发送和接受请求的。
3、原理3:前端发送ajax数据之所以受同源策略限制是因为服务端返回数据没有设置响应头,浏览器通过判断响应头来是否接受数据,所以我们就可以在服务端发送数据之前设置好响应头信息,即CORS方法
3、解决方法
1、script方法(客户端根据script元素标签属性自动生成jsonp方法)
1、须知<script>、<img>、<iframe>中的src属性都是通过get方式将请求的数据下载下来(下载的数据是字符串形式的变量),然后通过本地的js渲染下载的数据,就和服务端中数据一摸一样。
eg:客户端设置代码(客户端代码必须是在html头中先定义相对应的函数,然后再访问域名)
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function fun(arg) {
alert(arg)
}
</script>
<script src="http://127.0.0.1:8000/get_data.html"></script> </head>
服务端设置代码(服务端是直接返回一个带有客户端函数名称的字符串,说白了就是要符合js语法的字符串)
def get_data(request):
return HttpResponse('fun("机密数据")')
2、input方法(客户端根据input元素标签属性手动生成jsonp方法)
eg:客户端设置代码(客户端代码在html的body中设置一个onclick事件,只要一触发就在在html头中添加script标签然后执行相应的函数)
<body>
<h1>皇家赌场</h1>
<input type="text" />
<div id="i1"></div>
<input type="button" onclick="jsonp('http://127.0.0.1:8000/get_data.html')" value="发送JSONP请求"/>
<script src="/static/jquery-3.2.1.js"></script>
<script>
function fun(arg) {
alert(arg); document.head.removeChild(tag);
} function jsonp(url){
tag = document.createElement('script');
tag.src = url;
document.head.appendChild(tag);
}
</script>
服务端同1
3、input方法+url方法(客户端根据url传递的相应参数使服务端返回相对应的字符串)
eg:客户端设置代码(客户端代码设置与方法2雷同,但是在url路径上加入了相应的参数)
<body>
<h1>皇家赌场</h1>
<input type="text" />
<div id="i1"></div> <input type="button" onclick="jsonp('http://127.0.0.1:8000/get_data.html?callback=funcvvvvvv')" value="发送JSONP请求"/>
<script src="/static/jquery-3.2.1.js"></script>
<script>
function funcvvvvvv(arg) {
alert(arg); document.head.removeChild(tag);
} function jsonp(url){
tag = document.createElement('script');
tag.src = url;
document.head.appendChild(tag);
}
</script>
服务端代码设置(根据客户端传递过来的值返回相应的字符串给客户端)
def get_data(request):
func_name = request.GET.get('callback')
return HttpResponse('%s("机密数据")' %func_name)
注释:以上三种方法不是通过ajax方式发送的数据,不受同源策略的限制
4、jsonp方法
eg:客户端代码(客户端通过jsonp方式发送ajax实际上不是发送ajax请求,而是把ajax内的数据转换成script标签和相应的函数,根据script标签属性来发送数据)
<body>
<h1>皇家赌场</h1>
<input type="text"/>
<div id="i1"></div> <input type="button" onclick="Jsonp2()" value="发送JSONP2请求"/> <script src="/static/jquery-3.2.1.js"></script>
<script>
function Jsonp2() {
$.ajax({
url: "http://127.0.0.1:8000/get_data.html",
type: 'GET',
dataType: 'JSONP',
success: function (data) {
alert(data);
}
})
}
</script>
服务端代码()jQuery32107032112019471077_1508251792310
def get_data(request):
func_name = request.GET.get('callback')
return HttpResponse('%s("机密数据")' %func_name)
5、jsonp完整版
eg:客户端代码(dataType告诉ajax我其实是通过生成script标签发送数据,jsonp实际上是向url上添加一个键值对来告诉客户端返回的字符串的格式,jsonpCallback实际上是客户端接受到数据后执行对应的函数)
<body>
<h1>皇家赌场</h1>
<input type="button" onclick="Jsonp3()" value="发送JSONP3请求"/> <script src="/static/jquery-3.2.1.js"></script>
<script>
function Jsonp3() {
$.ajax({
url: "http://127.0.0.1:8000/get_data.html",
type: 'GET',
dataType: 'JSONP',
jsonp: 'callback',
jsonpCallback: 'list'
})
}
function list(arg) {
console.log(arg)
alert(arg)
} </script>
</body>
eg:服务端代码
def get_data(request):
func_name = request.GET.get('callback')
return HttpResponse('%s("机密数据")' %func_name)
2、代理方法
在python中可以通过requests模块来实现代理
3、CORS方法(之前已经讲了cors方法主要是在服务器端设置返回的响应头信息)
1、在客户端设置代码(直接通过ajax发送数据)
<body>
<h1>皇家赌场</h1>
<script src="/static/jquery-3.2.1.js"></script>
<script>
$.ajax({
url: "http://127.0.0.1:8000/get_data.html?xxx=666",
type: 'GET',
success: function(data){
console.log(data);
}
})
</script>
</body>
2、在服务端局部设置响应头(*代表匹配所有,也可以跟正则表达式匹配)
def get_data(request):
response = HttpResponse("机密数据")
response['Access-Control-Allow-Origin'] = "*"
# response['Access-Control-Allow-Origin'] = "http://127.0.0.1:8000"
return response
3、如果想在全局设置响应头信息就可以直接在django中间件中设置
三、cors补充
1、简单请求 和 非简单请求(同时满足以下两个条件时,则是简单请求,否则为复杂请求)
条件:1、请求方式:HEAD、GET、POST
2、请求头信息: Accept Accept-Language Content-Language Last-Event-ID Content-Type 对应的值是以下三个中的任意一个 application/x-www-form-urlencoded multipart/form-data text/plain 简单请求:一次请求
非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输,"请求方式:OPTIONS
2、什么是预检? 预检其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息 3、如何预检? 1、如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过 Access-Control-Request-Method 2、 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过 Access-Control-Request-Headersdef get_data(request):
if request.method == "OPTIONS":
# 预检也要有返回值,可以为空,并且允许所以用户预检,允许预检方式为PUT,运行预检头的值为xxx
response = HttpResponse()
response['Access-Control-Allow-Origin'] = "*"
# response['Access-Control-Allow-Methods'] = "PUT"
response['Access-Control-Allow-Headers'] = "xxx"
response['Access-Control-Allow-Headers']="true"
return response
elif request.method == "GET":
response = HttpResponse("机密数据")
response['Access-Control-Allow-Origin'] = "*"
return response
客户端代码
function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
xhrFields:{withCredentials: true},#如果设置想要头必须加上这句话
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
ajax跨域资源共享的更多相关文章
- AJAX跨域资源共享 CORS 详解
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- 黑马学习Ajax 跨域资源共享 jQuery+jsonp实现
- AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载
1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...
- 跨域资源共享(CORS)--跨域ajax
几年前,网站开发者都因为ajax的同源策略而撞了南墙.当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 ...
- django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享
一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...
- Ajax跨域实现
Ajax Ajax,Asynchronus JavaScript and XML,字母意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术.用于异步地去获取XML作 ...
- Ajax跨域:jsonp还是CORS
跨域一般用jsonp,兼容性比较好.CORS是html5最新的XHR第二版本,不支持IE8,IE9,对移动端的支持非常好.但是考虑项目后期这部分会转到同域名下,而且网址不需要支持ie8,ie9,所以我 ...
- PhoneGap开发跨平台移动APP - 解决跨域资源共享
解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...
- [CORS:跨域资源共享] 同源策略与JSONP
Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...
随机推荐
- Android应用APP脱壳笔记
[TOC] 天下游 模拟定位技术点简析 通过代码分析初步猜测模拟定位用到的几处技术点: 获取了Root权限 通过反射获取 android.os.ServiceManager 对应的函数 getServ ...
- 下载The Swift Programming Language.mobi版
下载 The Swift Programming Language.mobi 下载 http://download.csdn.net/detail/swifttrain/7444501
- 初识WatiN
WatiN —— Web Application Testing In .Net 为什么会有WatiN? 给用户提供一个.Net平台下,将Web测试自动化的便捷途径. 如何通过WatiN来进行自动化测 ...
- 关于angularjs在IE里的坑——F12工具打开,功能正常,关闭之后,angularjs not working
前端时间在做项目的时候,用到了angularjs,期间,发现了一个奇葩的问题,就是在IE11浏览器下,点击下方图1上箭头所示的位置,将此处的开关变为图2中箭头所示的样子,但是发觉没有反应,开关还是灰色 ...
- .align
.align的作用是针对指令或数据的存放地址对齐.但不同的CPU架构,指令和数据的存储方式不同,也就导致对齐的计量单位不一样. i386:n对齐 ARM:2^n 对齐,ARM架构下,指令都是占32位, ...
- python模块学习之re
正则表达式本质就是表示某种规则的一串字符. 匹配的规则叫做模式(pattern),模式作用于对象. 模式和对象可以是Unicode或者字节,但是,不能够混用,比如:模式为Unicode,对象为字节,像 ...
- 李洪强iOS开发之OC[006] - 类和对象
- Java并发编程(十三)同步容器类
同步容器类 Vector.HashTable,我用的很少:Vecotr的实现和ArrayList挺接近的,不同的是Vector中很多的方法都用synchronized进行了同步.在不强调线程安全地时候 ...
- linux下独立core2.1部署发布过程
1.vs2017独立发布.linux-64 2.winscp上传到当前用户下面.ubuntu tsl64来讲 3.超级用户sudo su 4.zip解压缩 uzip xxx.zip -d ../../ ...
- Yii简单使用阿里云短信教程!
首先我们下载官方完整包的SDK官方标明了啊,PHP版本一定要不低于5.5下载后目录如下: 我们只需要将目录里的api_sdk复制出来到Yii项目的根目录的common模块下面的extensions文件 ...