同源策略

同源策略(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. JAVA入门[11]-jsp几点基础语法

    一.include <%@include file="copyright.jsp"%> <jsp:include page="copyright.jsp ...

  2. linux 磁盘管理三部曲——(3)mount挂载,/etc/fstab配置文件

    当我们分完区,并做好文件系统格式化,就到了最后的挂载mount了,挂载完毕就可以使用磁盘设备了. 一.什么是挂载,卸载 任何块设备都不能直接访问,需挂载在目录上访问 挂载: 将额外文件系统与根文件系统 ...

  3. 【jQuery入门】(5)---jQuery CSS

    jQuery  CSS      1.jQuery 文档操作方法        1.addClass() 方法: addClass() 方法向被选元素添加一个或多个类.该方法不会移除已存在的 clas ...

  4. python安装和环境变量的配置

    python安装和环境变量的配置 研究生阶段学习的需求,简单的学习了python的语法和基础之后产生了兴趣,有了想从基础把python学好用好的想法.因此在忙碌的学习中抽出时间,在每天花几个小时学习p ...

  5. iOS APP之间到跳转,以及热门应用,手机自带到应用跳转

    应用之间的跳转 在第一个APP中,做如下操作:1.在info.plist文件中的"信息属性列表"下添加一项:"URL类型"; 2.点开"URL类型&q ...

  6. [C/C++语言标准] ISO C99/ ISO C11/ ISO C++11/ ISO C++14 Downloads

    语言法典,C/C++社区人手一份,技术讨(hu)论(peng)必备 ISO IEC C99 https://files.cnblogs.com/files/racaljk/ISO_C99.pdf IS ...

  7. (一)基于阿里云的MQTT远程控制(Android 连接MQTT服务器,ESP8266连接MQTT服务器实现远程通信控制----简单的连接通信)

    如果不了解MQTT的可以看这篇文章  http://www.cnblogs.com/yangfengwu/p/7764667.html http://www.cnblogs.com/yangfengw ...

  8. 视觉SLAM

    SLAM:Simultaneous Localization And Mapping.中文:同时定位与地图重建. 它是指搭载特定传感器的主体,在没有实验先验信息的情况下,于运动过程中建立环境的模型,同 ...

  9. laravel框架一种方便的快速填充数据的方法

    首先大家都知道在laravel框架里是采用seeder来填充数据的,具体命令如下,请将如下的类名称替换成你具体的seeder类名. 首先创建seeder类 php artisan make:seede ...

  10. JavaBean转Map方法

    Map<String, Object> fieldMap =new HashMap<String, Object>(); BeanInfo beanInfo = Introsp ...