跨域 Ajax 其他可选技术 异步
最早的跨域方法之一就是使用这个,任何域的<img>和<script>元素都可以随便加载。
var img = new Image();
img.onload = img.onerror = function(){
alert(“Done!”);
};
img.src = “http://www.example.com/test?name=Nicholas”;
数据通过查询字符串的形式发送,返回的可能是任何东西,通常是一像素的图片或者204响应。缺点就是只能使用get方式并且无法获得响应数据。所以通常用于单向从浏览器发送数据给服务器。
JSONP(动态生成script)
全称JSON with padding ,是JSON的变形,它看起来就像JSON除了数据被一个函数调用的东西包裹着:
callback({ “name”: “Nicholas” });
当收到响应的时候,就会调用页面上的callback函数。因为JSONP是有效的JavaScript,当JSONP的响应输出到页面上后就会立刻执行。
function handleResponse(response){
alert(“You’re at IP address “ + response.ip + “, which is in “ +
response.city + “, “ + response.region_name);
}
var script = document.createElement(“script”);
script.src = “http://freegeoip.net/json/?callback=handleResponse”;
document.body.insertBefore(script, document.body.firstChild);
比起用image,可以从响应里获得数据了。问题是可以注入邪恶脚本。其次是很难检测是否失败了,虽然HTML5给script定义了onerror事件,但浏览器支持不好。只能用定时检测在一段时间里是否受到了响应
Comet
服务器给页面推送数据,而不是页面向服务器请求数据,这种方式让信息能够更接近实时,例如比赛分数,股票价格等。
comet有实现两种方式,long polling和streaming
long polling
相对于传统的polling(short polling),浏览器定时请求服务器看有没有新数据,服务器不管有没有可用数据都马上返回响应。而long polling等待有可用数据的时候才返回响应,浏览器收到响应后马上发起新的请求。
优点就是使用xhr对象配合setTimeOut就可以了。只需要管理什么时候发送请求。
第二种方式是HTTP streaming
它是指使用单一个请求在整个页面的生存周期里,浏览器向服务器发送一个请求然后服务器保持这个链接不断,周期性地向浏览器推送数据。因为服务器端的语言都支持把数据写到输出缓存里,然后flush给客户端,因此这就是HTTP streaming的核心了。
举例:
function createStreamingClient(url, progress, finished){
var xhr = new XMLHttpRequest(),
received = 0;
xhr.open(“get”, url, true);
xhr.onreadystatechange = function(){
var result;
if (xhr.readyState == 3){
//get only the new data and adjust counter
result = xhr.responseText.substring(received);
received += result.length;
//call the progress callback
progress(result);
} else if (xhr.readyState == 4){
finished(xhr.responseText);
}
};
xhr.send(null);
return xhr;
}
var client = createStreamingClient(“streaming.php”, function(data){
alert(“Received: “ + data);
}, function(data){
alert(“Done!”);
});
1、server-sent events
这是一个针对只读comet交互的接口,这个接口建立了和服务器的单向链接(当然你可以配合xhr来实现双向通信),服务器响应的时候必须包含一个MIME类型为text/event-stream,输出的信息以一种指定的给浏览器。这个接口支持short polling,long polling和HTTP streaming,它会自动重新连接当原连接断开时。
var source = new EventSource(“myevents.php”);
地址必须是同域的,和调用该对象所在域一致,该对象实例也有readystate属性:
0 代表正在连接服务器
1 代表链接打开
2 代表链接关闭
有三个事件:
open 当链接建立时触发
message 当从服务器收到新事件时触发
error 当无法建立连接触发
source.onmessage = function(event){
var data = event.data; 从服务器传回来的信息以字符串的形式保存在data属性里
//do something with the data
};
默认地,当和服务器的连接被关闭, EventSource 会重新连接,可以通过close方法断开连接,禁止重新连接
source.close();
服务器发送的事件带上MIME类型为 text/event-stream,以long-lasting HTTP响应返回。
格式如下:
data: foo
data: bar
data: foo
data: bar
每一个空格代表发送一个message事件,例如第三个message事件event.data 值为 “foo\nbar”
可以指定给事件加个ID标识:
data:foo
id: 1
这样在多个连接情况下,断开重连也能找到之前的位置咯
2、Web socket
目的是通过一个long-lasting链接来实现浏览器和客户端的双向沟通。
当建立这种连接的时候,一个HTTP请求发送给服务器初始化一个链接,当服务器响应时,该连接会从HTTP升级为Web socket协议。这意味着服务器需要是支持Web socket 协议的。
web socket普通连接为 ws://
安全连接为 wss://
好处是发送很小的数据,不受HTTP字节妨碍,使用小数据包让Web socket在移动应用很适合。
var socket = new WebSocket("ws://www.haha.com/server.php");
必须传入绝对地址,可以跨域,完全由服务器决定是否和请求域建立连接。
浏览器会尝试建立连接当WebSocket对象被实例化以后。类似xhr,它也有一个readystate属性,只是值不同:
0 正在建立连接
1 连接已经建立好
2 连接开始关闭
3 连接已经关闭
Websocket是没有readystatechange事件的,但有相对不同状态的处理事件。你可以使用close来关闭链接
socket.close();
调用close,readystate马上变为2最后变为3
发送数据给服务器:
socket.send(“haha");
因为Web socket只能发送plain text,你需要把复杂数据结构先序列化:
var message = {
time: new Date(),
text: “Hello world!”,
clientId: “asdfp8734rew”
};
socket.send(JSON.stringify(message));
当服务器像客户端发送信息时,会触发message事件,返回的数据也是字符串,需要手动解析:
var data = event.data;
//do something with data
};
Web socket只能用Dom 0事件添加方式:
socket.onopen = function(){
alert(“Connection established.”);
};
socket.onerror = function(){
alert(“Connection error.”);
};
socket.onclose = function(){
alert(“Connection closed.”);
};
只有close事件有额外信息在event对象里:
wasClean属性: 布尔值,表示链接是否被干净地关掉
code:服务器返回的状态代码,数字
season:服务器发送的字符串
socket.onclose = function(event){
console.log(“Was clean? “ + event.wasClean + “ Code=” + event.code + “ Reason=”
+ event.reason);
};
安全问题
1、浏览器和服务器可以接入修改URL,例如:/getuserinfo.php?uid=6,没办法阻止别人把uid改成别的,因此 getuserinfo.php需要做进一步验证
2、当一个未经授权的系统能够进来获取资源的时候,就意味着发生了跨网站请求伪造(csrf)攻击。
预防就是验证该请求发送发之前接入过这个资源:
方法1:要求请求资源时带有SSL证书
方法2:要求每个请求带上一个用来计算的taken
document.domain = 'a.com';var ifr = document.createElement('iframe');ifr.src = 'http://script.a.com/b.html';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; // 在这里操纵b.html alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);}; 跨域 Ajax 其他可选技术 异步的更多相关文章
- Ajax与跨域Ajax
Ajax 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上.对于传统的Web应用,一个简单操作需 ...
- 06: AJAX全套 & jsonp跨域AJAX
目录: 1.1 AJAX介绍 1.2 jQuery AJAX(第一种) 1.3 原生ajax(第二种) 1.4 iframe“伪”AJAX(第三种) 1.5 jsonp跨域请求 1.6 在tornad ...
- 使用$.getJSON实现跨域ajax请求
jQuery中常用getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数.原型如下: jQuery.getJSON( url, [data], [callba ...
- 跨域资源共享(CORS)--跨域ajax
几年前,网站开发者都因为ajax的同源策略而撞了南墙.当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 ...
- 第二百七十四节,同源策略和跨域Ajax
同源策略和跨域Ajax 什么是同源策略 尽管浏览器的安全措施多种多样,但是要想黑掉一个Web应用,只要在浏览器的多种安全措施中找到某种措施的一个漏洞或者绕过一种安全措施的方法即可.浏览器的各种保安措 ...
- 用JQuery的$.getJSON发起跨域Ajax请求
jQuery中常用getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数.原型如下: jQuery.getJSON( url, [data], [callba ...
- 在django中解决跨域AJAX
由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接收罢了. 浏览器同源 ...
- 跨域Ajax请求WebService方法
一.允许跨域Ajax请求,更改如下配置: 在要调用的WebService上面添加特性标签: 二.以如下返回用户信息的WebService方法为例 三.在另一个网站上通过Ajax访问webService ...
- 跨域Ajax请求 web.config文件配置
在web.config文件的<system.webServer>节点下面添加如下配置代码:<!--允许跨域ajax访问--> <httpProtocol> < ...
随机推荐
- Quartz源码——QuartzSchedulerThread.run() 源码分析(三)
QuartzSchedulerThread.run()是主要处理任务的方法!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析 ...
- Qt实现基本QMainWindow主窗口程序
这个实验用Qt实现基本QMainWindow主窗口 先上实验效果图 打开一个文件,读取文件类容 详细步骤: 1.打开Qt creator新建MainWindow工程 右键工程名添加新文件,mai ...
- C++PrimerPlus第6版 第四章——复合类型
1,复合类型主要包含:数组.结构.联合.枚举.类.指针.引用等. 2,数组.长度必须确定.即编译阶段,数组的长度就得确定好.所以只能使用常量(#define.const)声明数组长度.如果使用变量声明 ...
- 手把手教你用npm发布一个包,详细教程
我们已经实现了路由的自动化构建,但是我们可以看到,一大串代码怼在里面.当然你也可以说,把它封装在一个JS文件里面,然后使用require('./autoRoute.js')给引入进来,那也行.但是,为 ...
- SQLServer中SQL语句与可执行二进制语句
SQLServer可以执行正常SQL语句也可以执行被转换的二进制语句,一般会用此方法进行数据库注入操作,骗过基本的字符过滤 --将二进制格式转为普通SQL语句 ) = 0x53454C45435420 ...
- Yii 2.0 数据库操作总结
1. 概述 操作数据库有2种方式: DAO(data access object),不安全 ORM(onject relational mapping) 2. DAO Yii::app()->d ...
- C-Flex 与 box布局教程
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html -阮一峰老师 http://www.w3cplus.com/css3/flexbox- ...
- 【爬虫入门01】我第一只由Reuests和BeautifulSoup4供养的Spider
[爬虫入门01]我第一只由Reuests和BeautifulSoup4供养的Spider 广东职业技术学院 欧浩源 1.引言 网络爬虫可以完成传统搜索引擎不能做的事情,利用爬虫程序在网络上取得数据 ...
- jquery系列教程4-事件操作全解
点击打开: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件操作全解 jquery系列教程5-动 ...
- JIRA-6.3.6安装与破解
首先下载JIRA-6.3.6的安装包: wget http://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-6.3. ...