最近学习心得,记录一下
说到跨域请求先要讲同源策略。
1.同源策略
浏览器都遵守同源策略,即动态脚本不能访问不同源的的资源。同源:相同端口,相同协议,相同域名。
由于同源策略的限制,浏览器对跨域网络访问进行了限制
2.跨域网络访问
同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest
或 <img>
标签时则会受到同源策略的约束。交互通常分为三类:
- 通常允许进行跨域写操作(Cross-origin writes)。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight。
- 通常允许跨域资源嵌入(Cross-origin embedding)。之后下面会举例说明。
- 通常不允许跨域读操作(Cross-origin reads)。但常可以通过内嵌资源来巧妙的进行读取访问。例如可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或availability of an embedded resource.
以下是一些可以跨域内嵌的资源示例:
<script src="..."></script>标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
-
<link rel="stylesheet" href="...">标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。不同浏览器有不同的限制:
IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera。 -
<img>
嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,... -
<video>
和<audio>
嵌入多媒体资源。 -
<object>
,<embed>
和<applet>的插件。
@font-face
引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。-
<frame>
和<iframe>载入的任何资源。站点可以使用
X-Frame-Options消息头来阻止这种形式的跨域交互。
由于浏览器限制访问非同源内容,但是没有限制<script>标签访问非同源内容,也没有限制动态添加<script>标签
所以我们可以这样做:
// 本地html文件
<html>
<head>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
function sayHello(person){
alert(person.name + ', your gender is ' + person.<span style="font-family: Arial, Helvetica, sans-serif;">gendar</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
}
</script>
<script type="text/javascript" src="http://127.0.0.1:8000/test/?callback=jin" ></script>
</head>
<body>
</body>
</html>
<pre name="code" class="python">//django
def jsonp(request):
if 'callback' in request.REQUEST:
# a jsonp response!
data = {
'name':'sdsd',
'gendar':'F',
}
data = '%s(%s);' % (request.REQUEST['callback'], simplejson.dumps(data))
return HttpResponse(data, "text/javascript")
这样就调用第三方源的数据运行本地的sayHello,
也可以动态生成javascript
var url = 'http://127.0.0.1:8000/test/?callback=jin';
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
}
这样运行后在head上能看到一个
<script type="text/javascript" src="http://127.0.0.1:8000/test/?callback=jin" ></script>
对于ajax,引入了jsonp
什么是jsonp
要了解JSONP,不得不提一下JSON,那么什么是JSON ?
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
实现过程:客户端向服务器端发送请求并附带callback函数,服务器端返回相应的js代码,这个代码就是执行回调函数,参数就是服务器端返回的JSON数据
可以用$.getJSON,$.ajax,$.get实现
举例一:
function sign(){
$.ajax({
type: 'GET',
url: "http://127.0.0.1:8000/test/?callback=we",
data:{userId:39},
dataType:"JSONP",
jsonp:'callback',
success: function(data){
alert(data)
},
error: function(response){
}
});
举例二:
$.getJSON("http://127.0.0.1:8000/test/?callback=?",
function(result) {
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
});
有任何问题欢迎大家在下面留言指教(⊙o⊙)
参考文档:http://blog.csdn.net/chosen0ne/article/details/7333626,https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy