同源策略

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

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。  
==================================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> <script>
$("button").click(function(){
$.ajax({
url:"http://127.0.0.1:7766/SendAjax/",
type:"POST",
data:{"username":"test","csrfmiddlewaretoken":'{{ csrf_token }}',
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 json
print(request.POST,"+++++++++++")
return HttpResponse(json.dumps("hello"))

第一个主机

==================================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项目的view视图函数 def index(request):
return render(request,"index.html") from django.views.decorators.csrf import csrf_exempt @csrf_exempt
def SendAjax(request):
import json
print("++++++++") return HttpResponse(json.dumps("hello2"))

第二个主机

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

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

解决方案1:

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

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

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

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

  一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建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改为:

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改为:

<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请求

应用

示例项目

python与 Ajax跨域请求的更多相关文章

  1. 第113天:Ajax跨域请求解决方法

    一.原生JS实现ajax 第一步获得XMLHttpRequest对象 第二步:设置状态监听函数 第三步:open一个连接,true是异步请求 第四部:send一个请求,可以发送一个对象和字符串,不需要 ...

  2. Laravel中的ajax跨域请求

    最近接触Laravel框架ajax跨域请求的过程中遇到一些问题,在这里做下总结. 一开始发起ajax请求一直报500错误,搜索相关资料后发现Laravel要允许跨域请求可以加入Cors中间件,代码如下 ...

  3. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  4. 解决ajax跨域请求 (总结)

    ajax跨域请求,目前已用几种方法实现:   1)用原生js的xhr对象实现.                var url="http://freegeoip.net/json/" ...

  5. ASP.NET MVC 实现AJAX跨域请求方法《1》

    ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...

  6. $.ajax 跨域请求 Web Api

    WepApi确实方便好用,没有配置文件,一个apicontroller直接可以干活了.但今天用$.ajax跨域请求的时候总是获取不到数据,用fiddler一看确实抓到了数据,但回到$.ajax函数中, ...

  7. JQuery的Ajax跨域请求原理概述及实例

    今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发 JQuer ...

  8. Nginx 实现AJAX跨域请求

    在工作中遇到跨域请求的问题: AJAX从一个域请求另一个域会有跨域的问题.那么如何在nginx上实现ajax跨域请求呢?要在nginx上启用跨域请求,需要添加add_header Access-Con ...

  9. jQuery ajax跨域请求的解决方法

    在Ajax应用中,jQuery的Ajax请求是非常容易而且方便的,但是初学者经常会犯一个错误,那就是Ajax请求的url不是本地或者同一个服务器下面的URI,最后导致虽然请求200,但是不会返回任何数 ...

随机推荐

  1. 调用接口http封装

    public static String httpHandler(String URL,String xml){ try { URL url=new URL(URL); URLConnection c ...

  2. Shell编程中的变量作用域

    有两个shell脚本文件: a.sh name=Tom echo $name ./b.sh b.sh echo "name in b.sh:"$name 运行./a.sh时输出结果 ...

  3. javascript中的异步 macrotask 和 microtask 简介

    javascript中的异步 macrotask 和 microtask 简介 什么是macrotask?什么是microtask?在理解什么是macrotask?什么是microtask之前,我们先 ...

  4. NodeJs学习笔记(五)---单元测试补充

    今天早上继续研究Mocha,忽然发现一个问题,我的大部分程序都是需要登录验证的,所以需要预先登录之后才能进行下一步测试,就开始在网上找答案,发现没有这种资料,很疑惑,最后发现其实是自己太笨了,因为这个 ...

  5. 快看Sample代码,速学Swift语言(2)-基础介绍

    Swift语言是一个新的编程语言,用于iOS, macOS, watchOS, 和 tvOS的开发,不过Swift很多部分内容,我们可以从C或者Objective-C的开发经验获得一种熟悉感.Swif ...

  6. Noip2016换教室(期望+DP)

    Description 题目链接:Luogu Solution 这题结合了DP和概率与期望,其实只要稍微知道什么是期望就可以了, 状态的构造很关键,\(F[i][j][0/1]\)表示已经到第\(i\ ...

  7. 【Zookeeper】源码分析之服务器(三)之LeaderZooKeeperServer

    一.前言 前面分析了ZooKeeperServer源码,由于QuorumZooKeeperServer的源码相对简单,于是直接分析LeaderZooKeeperServer. 二.LeaderZooK ...

  8. geoserver安装部署步骤

    方式一:直接在geoserver官网下载zip源代码解压包,直接部署在tomcat里面运行geoserver: 方式二:下载安装包方式 以GeoServer2.8.5版本为准,安装之前必须要保证你机子 ...

  9. linux下制作镜像文件

    第一:制作iso镜像的方法: 把/dev/cdrom目录制作为镜像,名字为/root/rh1.iso 方法1:dd if=/dev/cdrom of=/root/rh1.iso 方法2:#cat /d ...

  10. 搭建和测试 Redis 主备和集群

    本文章只是自我学习用,不适宜转载. 1. Redis主备集群 1.1 搭建步骤 机器:海航云虚机(2核4GB内存),使用 Centos 7.2 64bit 操作系统,IP 分别是 192.168.10 ...