同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

示例:

项目1:

#################### http://127.0.0.1:8001项目的index
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<button>ajax</button>
{% csrf_token %}<script>$("button").click(function(){$.ajax({url:"http://127.0.0.1:7766/SendAjax/",type:"POST",data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},success:function(data){alert(123);alert(data)}})})
</script>
</body>
</html>#################### http://127.0.0.1:8001项目的views
def index(request):return render(request,"index.html")def ajax(request):import jsonprint(request.POST,"+++++++++++")return HttpResponse(json.dumps("hello"))

项目2:

#################### http://127.0.0.1:8002项目的index
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body><button>sendAjax</button>
{% csrf_token %}<script>$("button").click(function(){$.ajax({url:"/SendAjax/",type:"POST",data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},success:function(data){alert(data)}})})
</script>
</body>
</html>#################### http://127.0.0.1:8002项目的views
def index(request):return render(request,"index.html")from django.views.decorators.csrf import csrf_exempt
@csrf_exemptdef SendAjax(request):import jsonreturn HttpResponse(json.dumps("hello2"))

当点击项目1的按钮时,发送了请求,但是会发现报错如下:

已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:7766/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。

但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截。

Jsonp

jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

#################### http://127.0.0.1:8001/index
<button>ajax</button>
{% csrf_token %}<script>function func(name){alert(name)}
</script><script src="http://127.0.0.1:7766/SendAjax/"></script>#################### http://127.0.0.1:8002/
from django.views.decorators.csrf import csrf_exempt@csrf_exempt
def SendAjax(request):import json# dic={"k1":"v1"}return HttpResponse("func('yuan')")  # return HttpResponse("func('%s')"%json.dumps(dic))

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。

一般情况下,我们希望这个 scrip t标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过 javascrip t动态的创建script标签,这样我们就可以灵活调用远程服务了。

<button onclick="f()">sendAjax</button><script>function addScriptTag(src){var script = document.createElement('script');script.setAttribute("type","text/javascript");script.src = src;document.body.appendChild(script);document.body.removeChild(script);}function func(name){alert("hello"+name)}function f(){addScriptTag("http://127.0.0.1:7766/SendAjax/")}
</script>

为了更加灵活,现在将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调,将8001的f()改写为:

function f(){addScriptTag("http://127.0.0.1:7766/SendAjax/?callbacks=func")
}

8002的views改为:

function f(){addScriptTag("http://127.0.0.1:7766/SendAjax/?callbacks=func")
}

jQuery对JSONP的实现

getJSON

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法8001的html改为:

<button onclick="f()">sendAjax</button>
<script>function f(){$.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){alert("hello"+arg)});}</script>

8002的views不改动。

结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。

此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

$.ajax

8001的html改为:

<script>function f(){$.ajax({url:"http://127.0.0.1:7766/SendAjax/",dataType:"jsonp",jsonp: 'callbacks',jsonpCallback:"SayHi"});}function SayHi(arg){alert(arg);}
</script>

8002的views不改动。

当然,最简单的形式还是通过回调函数来处理:

<script>function f(){$.ajax({url:"http://127.0.0.1:7766/SendAjax/",dataType:"jsonp",            //必须有,告诉server,这次访问要的是一个jsonp的结果。jsonp: 'callbacks',          //jQuery帮助随机生成的:callbacks="wner"success:function(data){alert("hi "+data)}});}
</script>

jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了;

jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。

注意 JSONP一定是GET请求

应用

<input type="button" onclick="AjaxRequest()" value="跨域Ajax" />
<div id="container"></div><script type="text/javascript">function AjaxRequest() {$.ajax({url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',type: 'GET',dataType: 'jsonp',jsonp: 'callback',jsonpCallback: 'list',success: function (data) {$.each(data.data,function(i){var item = data.data[i];var str = "<p>"+ item.week +"</p>";$('#container').append(str);$.each(item.list,function(j){var temp = "<a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>";$('#container').append(temp);});$('#container').append("<hr/>");})}});}
</script>

CORS

简介

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

二、两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理,是不一样的。

* 简单请求和非简单请求的区别?简单请求:一次请求非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。* 关于“预检”
- 请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”=> 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过Access-Control-Request-Method=> 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过Access-Control-Request-Headers

支持跨域,简单请求

服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

支持跨域,复杂请求

由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method =‘put,delete’
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers = ‘content-type等头信息’

前端之同源策略 Jsonp 与 CORS相关推荐

  1. 跨域获取后台数据undefined_同源策略amp;JSONP跨域

    同源策略&JSONP跨域 同源策略 对于同源的定义,MDN给出了这样的解释:如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源. 如何确定两个页面是否同源,只要比较两个 ...

  2. 同源策略——浏览器安全卫士

    对于软件开发人员来说,理解同源策略.能够非常好地攻克了一个痛点. 不同域名下的资源读写 ! 古代的楚河汉界明白地规定了两方的活动界限.假设没有这些界限,天下必将大乱.相同,在我们的浏览器,也有着一些界 ...

  3. JavaScript 同源策略 跨域 JSONP CORS 防抖和节流

    同源策略与跨域 同源策略 定义 比较 通俗理解 跨域 定义 浏览器对跨域请求的拦截 实现跨域的两种方法 自定义JSONP jQuery的JSONP 防抖与节流 防抖 节流 总结 同源策略 定义 同源策 ...

  4. Django 【第十九篇】JS实现的ajax、同源策略和前端JSONP解决跨域问题

    一.回顾jQuery实现的ajax 首先说一下ajax的优缺点 优点:AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器响应内容不再是整个页面,而是页面 ...

  5. cors跨域资源共享】同源策略和jsonp

    在执行下面那段代码的时候,我遇到了一个跨域资源共享的问题 <!doctype html> <html> <head> <meta charset=" ...

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

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

  7. 同源策略:CORS和JSONP

    背景 同源策略(Same origin policy)是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会使用这个策略. 同源策略是一个重要的安全策略,它用于限制 ...

  8. AJAX | 跨域与JSONP + 同源策略和跨域 + JSONP + 防抖和节流 + 案例 – 淘宝搜索

    目录 同源策略和跨域 同源策略 跨域 JSONP JSONP的实现原理 自己实现一个简单的JSONP JSONP的缺点 jQuery中的JSONP 自定义参数及回调函数名称 jQuery中JSONP的 ...

  9. 新蜂商城(newbee-mall-api)部分接口实验,跨域处理(同源策略,跨域访问,CORS),系统安全问题(Session,Cookie,Token,OAuth)(软件工程综合实践课程第十三周)

    文章目录 一.要求 二.知识总结 跨域处理 1.同源策略 1.1 浏览器的同源策略 1.2 跨域请求实验 2 跨域访问 2.1 添加响应头来处理跨域 2.1.1 CORS 跨域资源共享 2.1.2 设 ...

最新文章

  1. python 播放 wav 文件
  2. 别再蒸馏3层BERT了!变矮又能变瘦的DynaBERT了解一下
  3. 《Unity 3D 游戏开发技术详解与典型案例》——1.3节第一个Unity 3D程序
  4. 使用Apache CXF开发SOAP Web服务
  5. 写一个函数,输入int型,返回整数逆序后的字符串
  6. SAS在金融中的应用三
  7. ScriptManager和ClientScriptManager
  8. 网络爬虫ip代理服务器【程序样例】
  9. 做形态学方法的团队_做好形态学实验教学准备工作的几点体会
  10. 国开计算机专业英语章节测试答案,国开大201x理工英语1第七单元网上测试答案...
  11. 设A和B是n阶矩阵 ,A,B,A+B均可逆,证明:(A^-1+B^-1)也可逆,并求其逆。
  12. ros2之tello无人机
  13. flag--命令行参数定义多标签示例
  14. 深度 | 蚂蚁金服DASFAA论文带你深入了解GBDT模型
  15. 关于 opengl3.3 - 4.1 ABO 的感触. 传统 VBO往 ABO+VBO的 代码移植
  16. 京东商品详情查询接口V1新版接口
  17. 用python画皮卡丘代码-用python画一只可爱的皮卡丘实例
  18. PHP 如何优(zhuang)雅(bi)的使用魔术方法__call()
  19. php 微擎钻石投票二开,[模块插件]微擎钻石投票男神女神公众号投票系统完美运营版其他-(微信)小程序...
  20. 3D 沙盒游戏之地面网格设计

热门文章

  1. 年薪50万码农转行卖凉皮,互联网思维又一次颠覆?
  2. 什么是 NoSQL 数据库、NoSQL 与 SQL 的区别
  3. WebService中文件传输
  4. 【Java】 大话数据结构(1) 线性表之顺序存储结构
  5. C++项目參考解答:累加求圆周率
  6. 20162314 《Program Design Data Structures》Learning Summary Of The First Week
  7. 使用 sitemesh/decorator装饰器装饰jsp页面(原理及详细配置)
  8. jquery的$.extend、$.fn.extend、 jQuery.extend( target, object1, [objectN])作用及区别
  9. [LeetCode]Search Insert Position
  10. 猫:君主般的眼神 监视领地。 狗