一、同域发送数据

  略

二、跨域发送数据

  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
   2、简单请求和非简单请求的区别?
     简单请求:一次请求

     非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输,"
   3、关于“预检”
     1、请求方式:OPTIONS

     2、什么是预检
        预检其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
     3、如何预检?
       1、如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
        Access-Control-Request-Method
       2、 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
        Access-Control-Request-Headers
     4、基于cors实现AJAX请求:
      1、支持跨域,简单请求(略)
      2、支持跨域,复杂请求
        由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据,所以:
          “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method  
          “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
          “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age
          eg:服务端代码

def 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跨域资源共享的更多相关文章

  1. AJAX跨域资源共享 CORS 详解

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  2. 黑马学习Ajax 跨域资源共享 jQuery+jsonp实现

  3. AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载

    1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...

  4. 跨域资源共享(CORS)--跨域ajax

    几年前,网站开发者都因为ajax的同源策略而撞了南墙.当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 ...

  5. 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 ...

  6. Ajax跨域实现

    Ajax Ajax,Asynchronus JavaScript and XML,字母意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术.用于异步地去获取XML作 ...

  7. Ajax跨域:jsonp还是CORS

    跨域一般用jsonp,兼容性比较好.CORS是html5最新的XHR第二版本,不支持IE8,IE9,对移动端的支持非常好.但是考虑项目后期这部分会转到同域名下,而且网址不需要支持ie8,ie9,所以我 ...

  8. PhoneGap开发跨平台移动APP - 解决跨域资源共享

    解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...

  9. [CORS:跨域资源共享] 同源策略与JSONP

    Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...

随机推荐

  1. [ci]gitlab安装配置(含gitlab邮件配置)

    gitlab安装配置 参考: https://www.unixhot.com/article/48 原则:简单维护为准,故yum安装gitlab 1,gitlab安装 2,gitlab邮箱配置 1,g ...

  2. 92. Reverse Linked List II【Medium】

    92. Reverse Linked List II[Medium] Reverse a linked list from position m to n. Do it in-place and in ...

  3. 初尝CDN:什么是分布式服务节点?

    什么是CDN?笔者初见时也是摸不着头脑,查阅了大量的资料才明白什么是CDN,笔者为您揭秘什么是CDN? CDN的全称是Content Delivery Network,即内容分发网络.CDN的通俗理解 ...

  4. ACM Computer Factory - poj 3436 (最大流)

      Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5949   Accepted: 2053   Special Judge ...

  5. Web Services 平台元素

    Web Services 拥有三种基本的元素:SOAP.WSDL 以及 UDDI. 什么是 SOAP? 基本的 Web services 平台是 XML + HTTP. SOAP 指简易对象访问协议 ...

  6. Theano mnist数据集格式

    首先链接一篇大牛的Theano文档翻译:http://www.cnblogs.com/xueliangliu/archive/2013/04/03/2997437.html 里面有mnist.pkl. ...

  7. poj 1515+poj 1438(边双连通)

    题目链接:http://poj.org/problem?id=1515 思路:题目的意思是说将一个无向图改成有向图,使其成为强连通,输出所有的边.我们可以求无向图的边双连通分量,对于同一个双连通分量, ...

  8. PHP POST, GET 参数过滤,预防sql注入函数

    1. 实际过滤函数 可适当修改其中的正则表示式 1 static public function filterWords(&$str) 2 { 3 $farr = array( 4 " ...

  9. YII配置rabbitMQ时前期工作各种坑

    背景如下: 项目需要做一个订阅/发布的功能,然后一大堆讨论不做说明,确认使用rabbitMQ来做: okay,既然 要这个来做,我们下载这个东西吧!在官网上下载就okay了,不做说明,下载安装的时候会 ...

  10. Windows Azure 免费初体验 - 创建部署网站

    前几天在看到有个学Windows Azure课程,送Windows Azure的活动,课程地址:http://www.microsoftvirtualacademy.com/ 在活得体验资格后,就迫不 ...