数据库怎么做两个网站,网站关键词怎么修改,php网站建设找哪家好,dede网站不能运行php文件同源策略
同源策略#xff08;Same origin policy#xff09;是一种约定#xff0c;它是浏览器最核心也最基本的安全功能#xff0c;如果缺少了同源策略#xff0c;则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的#xff0c;浏览器只是针对同…同源策略
同源策略Same origin policy是一种约定它是浏览器最核心也最基本的安全功能如果缺少了同源策略则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的浏览器只是针对同源策略的一种实现。
同源策略它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指域名协议端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的即检查是否同源只有和百度同源的脚本才会被执行。如果非同源那么在请求数据时浏览器会在控制台中报一个异常提示拒绝访问。
示例
项目1:
#################### http://127.0.0.1:8001项目的index
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlescript srchttp://code.jquery.com/jquery-latest.js/script
/head
body
buttonajax/button
{% csrf_token %}script$(button).click(function(){$.ajax({url:http://127.0.0.1:7766/SendAjax/,type:POST,data:{username:yuan,csrfmiddlewaretoken:$([namecsrfmiddlewaretoken]).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 langen
headmeta charsetUTF-8titleTitle/titlescript srchttp://code.jquery.com/jquery-latest.js/script
/head
bodybuttonsendAjax/button
{% csrf_token %}script$(button).click(function(){$.ajax({url:/SendAjax/,type:POST,data:{username:yuan,csrfmiddlewaretoken:$([namecsrfmiddlewaretoken]).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
buttonajax/button
{% csrf_token %}scriptfunction func(name){alert(name)}
/scriptscript srchttp://127.0.0.1:7766/SendAjax//script#################### http://127.0.0.1:8002/
from django.views.decorators.csrf import csrf_exemptcsrf_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的JSONPadding的含义。
一般情况下我们希望这个 scrip t标签能够动态的调用而不是像上面因为固定在html里面所以没等页面显示就执行了很不灵活。我们可以通过 javascrip t动态的创建script标签这样我们就可以灵活调用远程服务了。
button onclickf()sendAjax/buttonscriptfunction 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(helloname)}function f(){addScriptTag(http://127.0.0.1:7766/SendAjax/)}
/script
为了更加灵活现在将你自己在客户端定义的回调函数的函数名传送给服务端服务端则会返回以你定义的回调函数名的方法将获取的json数据传入这个方法完成回调,将8001的f()改写为
function f(){addScriptTag(http://127.0.0.1:7766/SendAjax/?callbacksfunc)
}
8002的views改为
function f(){addScriptTag(http://127.0.0.1:7766/SendAjax/?callbacksfunc)
}
jQuery对JSONP的实现
getJSON
jQuery框架也当然支持JSONP可以使用$.getJSON(url,[data],[callback])方法8001的html改为
button onclickf()sendAjax/button
scriptfunction f(){$.getJSON(http://127.0.0.1:7766/SendAjax/?callbacks?,function(arg){alert(helloarg)});}/script
8002的views不改动。
结果是一样的要注意的是在url的后面必须添加一个callback参数这样getJSON方法才会知道是用JSONP方式去访问服务callback后面的那个问号是内部自动生成的一个回调函数名。
此外如果说我们想指定自己的回调函数名或者说服务上规定了固定回调函数名该怎么办呢我们可以使用$.ajax方法来实现 $.ajax
8001的html改为
scriptfunction f(){$.ajax({url:http://127.0.0.1:7766/SendAjax/,dataType:jsonp,jsonp: callbacks,jsonpCallback:SayHi});}function SayHi(arg){alert(arg);}
/script
8002的views不改动。
当然最简单的形式还是通过回调函数来处理
scriptfunction f(){$.ajax({url:http://127.0.0.1:7766/SendAjax/,dataType:jsonp, //必须有告诉server这次访问要的是一个jsonp的结果。jsonp: callbacks, //jQuery帮助随机生成的callbackswnersuccess:function(data){alert(hi data)}});}
/script
jsonp: callbacks就是定义一个存放回调函数的键jsonpCallback是前端定义好的回调函数方法名SayHiserver端接受callback键对应值后就可以在其中填充数据打包返回了;
jsonpCallback参数可以不定义jquery会自动定义一个随机名发过去那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。
注意 JSONP一定是GET请求
应用
input typebutton onclickAjaxRequest() value跨域Ajax /
div idcontainer/divscript typetext/javascriptfunction AjaxRequest() {$.ajax({url: http://www.jxntv.cn/data/jmd-jxtv2.html?callbacklist_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 /abr/;$(#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 2HTTP的头信息不超出以下几种字段 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 ‘putdelete’“预检”请求时允许请求头则需服务器设置响应头Access-Control-Request-Headers ‘content-type等头信息’