同源策略

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

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

示例:

项目1:

  1. ==================================http://127.0.0.1:8001项目的index
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <script src="http://code.jquery.com/jquery-latest.js"></script>
  8. </head>
  9. <body>
  10.  
  11. <button>ajax</button>
  12. {% csrf_token %}
  13.  
  14. <script>
  15. $("button").click(function(){
  16.  
  17. $.ajax({
  18. url:"http://127.0.0.1:7766/SendAjax/",
  19. type:"POST",
  20. data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
  21. success:function(data){
  22. alert();
  23. alert(data)
  24. }
  25. })
  26. })
  27. </script>
  28. </body>
  29. </html>
  30.  
  31. ==================================http://127.0.0.1:8001项目的views
  32.  
  33. def index(request):
  34.  
  35. return render(request,"index.html")
  36.  
  37. def ajax(request):
  38. import json
  39. print(request.POST,"+++++++++++")
  40. return HttpResponse(json.dumps("hello"))

项目2:

  1. ==================================http://127.0.0.1:8002项目的index
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <script src="http://code.jquery.com/jquery-latest.js"></script>
  8. </head>
  9. <body>
  10.  
  11. <button>sendAjax</button>
  12.  
  13. {% csrf_token %}
  14.  
  15. <script>
  16. $("button").click(function(){
  17.  
  18. $.ajax({
  19. url:"/SendAjax/",
  20. type:"POST",
  21. data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
  22. success:function(data){
  23. alert(data)
  24. }
  25. })
  26. })
  27. </script>
  28.  
  29. </body>
  30. </html>
  31.  
  32. ==================================http://127.0.0.1:8002项目的views
  33.  
  34. def index(request):
  35.  
  36. return render(request,"index.html")
  37.  
  38. from django.views.decorators.csrf import csrf_exempt
  39.  
  40. @csrf_exempt
  41.  
  42. def SendAjax(request):
  43.  
  44. import json
  45.  
  46. print("++++++++")
  47.  
  48. return HttpResponse(json.dumps("hello2"))

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

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

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

Jsonp

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

思考:这算怎么回事?

1
<script src="http://code.jquery.com/jquery-latest.js"></script>

借助script标签,实现跨域请求,示例:

  1. # =============================http://127.0.0.1:8001/index
  2.  
  3. <button>ajax</button>
  4. {% csrf_token %}
  5.  
  6. <script>
  7. function func(name){
  8. alert(name)
  9. }
  10. </script>
  11.  
  12. <script src="http://127.0.0.1:7766/SendAjax/"></script>
  13.  
  14. # =============================http://127.0.0.1:8002/
  15. from django.views.decorators.csrf import csrf_exempt
  16.  
  17. @csrf_exempt
  18.  
  19. def SendAjax(request):
  20.  
  21. import json
  22.  
  23. print("++++++++")
  24. # dic={"k1":"v1"}
  25. return HttpResponse("func('yuan')") # return HttpResponse("func('%s')"%json.dumps(dic))

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

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

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

  1. <button onclick="f()">sendAjax</button>
  2.  
  3. <script>
  4. function addScriptTag(src){
  5. var script = document.createElement('script');
  6. script.setAttribute("type","text/javascript");
  7. script.src = src;
  8. document.body.appendChild(script);
  9. document.body.removeChild(script);
  10. }
  11.  
  12. function func(name){
  13. alert("hello"+name)
  14. }
  15.  
  16. function f(){
  17. addScriptTag("http://127.0.0.1:7766/SendAjax/")
  18. }
  19. </script>

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

将8001的f()改写为:

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

8002的views改为:

1
2
3
4
5
6
7
8
9
10
def SendAjax(request):
 
    import json
 
    dic={"k1":"v1"}
 
    print("callbacks:",request.GET.get("callbacks"))
    callbacks=request.GET.get("callbacks")
 
    return HttpResponse("%s('%s')"%(callbacks,json.dumps(dic)))

jQuery对JSONP的实现

getJSON

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

8001的html改为:

  1. <button onclick="f()">sendAjax</button>
  2.  
  3. <script>
  4.  
  5. function f(){
  6. $.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){
  7. alert("hello"+arg)
  8. });
  9. }
  10.  
  11. </script>

8002的views不改动。

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

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

$.ajax

8001的html改为:

  1. <script>
  2.  
  3. function f(){
  4. $.ajax({
  5. url:"http://127.0.0.1:7766/SendAjax/",
  6. dataType:"jsonp",
  7. jsonp: 'callbacks',
  8. jsonpCallback:"SayHi"
  9. });
  10.  
  11. }
  12.  
  13. function SayHi(arg){
  14. alert(arg);
  15. }
  16.  
  17. </script>

8002的views不改动。

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

  1. <script>
  2.  
  3. function f(){
  4.  
  5. $.ajax({
  6. url:"http://127.0.0.1:7766/SendAjax/",
  7. dataType:"jsonp", //必须有,告诉server,这次访问要的是一个jsonp的结果。
  8. jsonp: 'callbacks', //jQuery帮助随机生成的:callbacks="wner"
  9. success:function(data){
  10. alert("hi "+data)
  11. }
  12. });
  13.  
  14. }
  15.  
  16. </script>

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

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

注意 JSONP一定是GET请求

应用

  1. <input type="button" onclick="AjaxRequest()" value="跨域Ajax" />
  2.  
  3. <div id="container"></div>
  4.  
  5. <script type="text/javascript">
  6. function AjaxRequest() {
  7. $.ajax({
  8. url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',
  9. type: 'GET',
  10. dataType: 'jsonp',
  11. jsonp: 'callback',
  12. jsonpCallback: 'list',
  13. success: function (data) {
  14.  
  15. $.each(data.data,function(i){
  16. var item = data.data[i];
  17. var str = "<p>"+ item.week +"</p>";
  18. $('#container').append(str);
  19. $.each(item.list,function(j){
  20. var temp = "<a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>";
  21. $('#container').append(temp);
  22. });
  23. $('#container').append("<hr/>");
  24. })
  25.  
  26. }
  27. });
  28. }
  29. </script>

CORS

一、简介

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

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

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

二、两种请求

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

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

  1. 1) 请求方法是以下三种方法之一:
  2. HEAD
  3. GET
  4. POST
  5. 2HTTP的头信息不超出以下几种字段:
  6. Accept
  7. Accept-Language
  8. Content-Language
  9. Last-Event-ID
  10. Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

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

支持跨域,简单请求

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

支持跨域,复杂请求

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

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers

第十九篇 同源策略与Jsonp的更多相关文章

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

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

  2. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

  3. 同源策略与JSONP

    [CORS:跨域资源共享] 同源策略与JSONP Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分.“同源策略”限制了J ...

  4. 同源策略与 JSONP CORS

    同源策略与 JSONP CORS 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以 ...

  5. Egret入门学习日记 --- 第十九篇(书中 8.8~8.10 节 内容)

    第十九篇(书中 8.8~8.10 节 内容) 开始 8.8节. 重点: 1.类型推断. 2.类型强制转换,使其拥有代码提示功能. 3.除了TS自带的类型判断,Egret官方也提供了类型判断的方法. 操 ...

  6. 同源策略和Jsonp、CORS

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

  7. 同源策略和JSONP(概念性)

    同源策略 浏览器有一个很重要的概念——同源策略(Same-Origin Policy). 所谓同源是指,域名,协议,端口相同.不同源的客户端脚本(javascript.ActionScript)在没明 ...

  8. Ajax跨域请求 同源策略与Jsonp

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

  9. javascript 同源策略和 JSONP 的工作原理

    同源策略 同源策略是一个约定,该约定阻止当前脚本获取或操作另一域的内容.同源是指:域名.协议.端口号都相同. 简单地说,A 服务器下的 a 端口执行 ajax 程序,不能获取 B 服务器或者 A 服务 ...

随机推荐

  1. 【转载】将Centos的yum源更换为国内的阿里云源

    自己的yum源不知道什么时候给改毁了--搜到了个超简单的方法将yum源更换为阿里的源 完全参考 http://mirrors.aliyun.com/help/centos?spm=5176.bbsr1 ...

  2. 回顾PHP:第一章:PHP基础语法(2)

    十.PHP常量和变量——用常量限制用户跳过某些文件(重要) 十.1常量在代码中定义.书写方式: define(常量名,常量值) 注:1.常量值只能为标量 2.常量名可以小写,但是通常大写 3.常量名可 ...

  3. Pytorch 分割模型构建和训练【直播】2019 年县域农业大脑AI挑战赛---(四)模型构建和网络训练

    对于分割网络,如果当成一个黑箱就是:输入一个3x1024x1024 输出4x1024x1024. 我没有使用二分类,直接使用了四分类. 分类网络使用了SegNet,没有加载预训练模型,参数也是默认初始 ...

  4. POJ 1487:Single-Player Games 浮点数高斯消元

    Single-Player Games Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1287   Accepted: 36 ...

  5. 学会使用Google hacking

    https://klionsec.github.io/2014/12/14/search-hacking/ 熟练利用Google hacking 来辅助我们快速渗透 http://www.sec-re ...

  6. Java导出Excel(项目实战Demo)

    Controller 层 /** * 考勤机刷卡明细导出Excel * * @throws Exception */ // @RequiresPermissions("report:Expo ...

  7. SSH框架系列:Spring AOP应用记录日志Demo

    分类: [java]2013-12-10 18:53 724人阅读 评论(0) 收藏 举报 1.简介 Spring 中的AOP为Aspect Oriented Programming的缩写,面向切面编 ...

  8. AssetBundle打包依赖(宽宽又欠我一顿烧烤)

    using UnityEngine; using System.Collections; using UnityEditor; public class dabao : EditorWindow { ...

  9. Docker registry自签名证书

    权威Registry 获取安全证书有两个办法:互联网认证的CA处获取.自建CA自己给自己签名. 1.从认证CA处获取签名证书,大多数是需要付出一定费用的,近些年也有认证CA提供免费证书,例如Let’s ...

  10. 题解 hdu4624 Endless Spin

    题目链接 题目大意: 有长度为\(n\)的区间,每次随机选择一段(左右端点都是整数)染黑,问期望多少次全部染黑. \(n\leq 50\) 设\(n\)个随机变量\(t_1,...,t_n\).\(t ...