Ajax:js自执行函数、jsonp、cros
一、js自执行函数
#(function(){alert(1);})(); (function(){
alert(1);
}
)();
二、javascript同源策略
1. 什么是同源策略
理解跨域首先必须要了解同源策略。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。
何谓同源:
URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
同源策略:
浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。
从一个域上加载的脚本不允许访问另外一个域的文档属性。
举个例子:
比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,而不受同源限制,但浏览器限制了JavaScript的权限使其不能读、写加载的内容。
另外同源策略只对网页的HTML文档做了限制,对加载的其他静态资源如javascript、css、图片等仍然认为属于同源。
特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。
浏览器同源策略并不是对所有的请求均制约:
- 制约: XmlHttpRequest
- 不受影响: img、iframe、script等具有src属性的标签
跨域,跨域名访问,如:http://www.c1.com 域名向 http://www.c2.com域名发送请求。
三、实现跨域请求(1): img、iframe、script等具有src属性的标签
利用 img、iframe、script等具有src属性的标签
#服务端视图函数
def get_data(request):
import time
time.sleep(2)
func_name = request.GET.get('callback')
return HttpResponse('%s("机密数据")' %func_name) #客户端js代码
function callback_func(arg) {
alert(arg);
document.head.removeChild(tag);
}
function jsonp(url){
tag = document.createElement('script');
tag.src = url+'?callback=callbackfunc';
document.head.appendChild(tag);
}
四、实现跨域请求(2):JSONP实现跨域请求
JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域),即利用script标签跨域访问的一种方式
注:Jsonp 不能发送Post请求
#服务端视图函数
def get_data(request):
import time
time.sleep(2)
func_name = request.GET.get('callback')
return HttpResponse('%s("机密数据")' %func_name) #客户端js代码
function Jsonp2(){
$.ajax({
url: "http://127.0.0.1:8000/get_data.html",
type: 'GET',
dataType: 'JSONP',
success: function(data){
console.log(data);
}
})
} function list(arg) {
console.log(arg);
}
function Jsonp3(){
$.ajax({
url: "http://www.jxntv.cn/data/jmd-jxtv2.html",
type: 'GET',
dataType: 'JSONP',
jsonp: 'callback',
jsonpCallback: 'list'
})
}
五、实现跨域请求(3):CORS
随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。
* 简单请求 OR 非简单请求
条件:
1、请求方式:HEAD、GET、POST
2、请求头信息:
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
基于cors实现AJAX请求:
a、支持跨域,简单请求
服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('GET', "http://c2.com:8000/test/", true);
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'text',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>
HTML
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}')
Torando
b、支持跨域,复杂请求
由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。
- “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
- “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
- “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>
HTML
class MainHandler(tornado.web.RequestHandler): def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)
Tornado
c、跨域获取响应头
默认获取到的所有响应头只有基本信息,如果想要获取自定义的响应头,则需要再服务器端设置Access-Control-Expose-Headers。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
// 获取响应头
console.log(xhr.getAllResponseHeaders());
}
};
xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
// 获取响应头
console.log(xmlHttpRequest.getAllResponseHeaders());
}
})
} </script>
</body>
</html>
HTML
class MainHandler(tornado.web.RequestHandler): def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('xxoo', "seven")
self.set_header('bili', "daobidao") self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)
Tornado
d、跨域传输cookie
在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。
如果想要发送:
- 浏览器端:XMLHttpRequest的withCredentials为true
- 服务器端:Access-Control-Allow-Credentials为true
- 注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 *
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
}; xhr.withCredentials = true; xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
xhrFields:{withCredentials: true},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>
HTML
class MainHandler(tornado.web.RequestHandler): def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Credentials', "true") self.set_header('xxoo', "seven")
self.set_header('bili', "daobidao")
self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.set_cookie('kkkkk', 'vvvvv'); self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)
Tornado
Ajax:js自执行函数、jsonp、cros的更多相关文章
- js基础 js自执行函数、调用递归函数、圆括号运算符、函数声明的提升 js 布尔值 ASP.NET MVC中设置跨域
js基础 目录 javascript基础 ESMAScript数据类型 DOM JS常用方法 回到顶部 javascript基础 常说的js包括三个部分:dom(文档document).bom(浏览器 ...
- js立即执行函数
一.JS立即执行函数的写法 方式1.最前最后加括号 (function(){alert(1);}()); 方式2.function外面加括号 (function(){alert(1);})(); ...
- 模板语言变量,js变量,js自执行函数之前嵌套调用
1.模板语言变量 前端html页面中展示 {{ nodeIp }} 2.js变量引用模板语言变量 把模板语言变量传递给js,js去执行页面操作(变量的转换,只适用于字符串) var IP = &quo ...
- js立即执行函数用法
js立即执行函数可以让你的函数在创建后立即执行,js立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行. 一.JS立即执行 ...
- js自执行函数的常见写法
js自执行函数的常见写法 2016-12-20 20:02:26 1.关于自执行函数 1.1 写自执行函数的好处:独立的作用域,不会污染全局环境 (function() { })(); 1.2 理解重 ...
- js立即执行函数应用--事件绑定
js中立即执行函数的应用:应用到事件绑定上. 少说多做,直接运行代码(代码中有注释): <!DOCTYPE html> <html lang="zh"> & ...
- js 立即执行函数定义方法
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- JS 自执行函数
由于自己js基础知识薄弱,很多js的知识还没有掌握,所以接下来会经常写一些关于js基础知识的博客,也算给自己提个醒吧. js自执行函数,听到这个名字,首先会联想到函数.接下来,我来定义一个函数: fu ...
- js自执行函数、调用递归函数、圆括号运算符、函数声明的提升
前言 起因是我要在jquery的ajax中需要根据返回值来决定是否继续发起ajax请求,这是一个有条件的循环,符合条件就跳出.可以使用while循环的,但是想了想还是递归调用好用. 调用递归函数 递归 ...
随机推荐
- C++在线编译器
主要有3个,且它们都支持C++11 http://gcc.godbolt.org/ http://coliru.stacked-crooked.com/ http://ideone.com/ 第一个网 ...
- mysql数据库记录
ON DELETE restrict(约束):当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除. no action:意思同restrict.即如果存在从数 ...
- phxsql安装小记
PhxSQL具有服务高可用.数据强一致.高性能.运维简单.和MySQL完全兼容的特点. 服务高可用:PhxSQL集群内只要多数派节点存活就能正常提供服务:出于性能的考虑,集群会选举出一个Master节 ...
- 如何让git小乌龟工具TortoiseGit记住你的账号密码
在使用小乌龟的过程中,发下每次push或者pull都要重复输入账号密码,非常麻烦. 如果能记住账号密码就好了,这样就省去了时间. 怎么设置记住密码 在[系统盘]:\Users[你的用户名]下面,有一个 ...
- Servlet 表单数据
很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序.浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法. GET 方法 GET 方法向页 ...
- Spring MVC多项单选按钮
以下示例显示如何在使用Spring Web MVC框架的表单中使用多选按钮(RadioButton).首先使用Eclipse IDE来创建一个WEB工程,实现一个让用户可选择自己喜欢的数字的功能.并按 ...
- 获取云硬盘列表bug
有段时间没写博客了,主要还是刚进新公司,多少有点不适应(真会给自己找理由,明明是手里没技术,肚子里没货,能写啥!).前面几个星期都在修一修horizon的bug,这个没啥很大难度,就是用了一个djan ...
- 防火墙系列之firewall
firewalld 介绍 防火墙守护 firewalld 服务引入了一个信任级别的概念来管理与之相关联的连接与接口.它支持 ipv4 与 ipv6,并支持网桥,采用 firewall-cmd (com ...
- iOS内存管理之浅见
当我们用alloc.new.copy创建对象时,对象的应用计数为1,当把这个对象retain时.引用计数+1.当对这个对象发送release消息时,引用计数-1,当对象的引用计数为0时,系统回收这个对 ...
- 三维空间直线最近点对hdu4741
//求两条直线之间的关系(三维) //输入:两条不为点的直线 //输出:相交返回XIANGJIAO和交点p,平行返回PINGXING,共线返回GONGXIAN int LineAndLine(Line ...