Ajax
表单提交
在HTML中提供了表单提交的功能,我们可以通过表单把数据从前台提交到后台
<body>
<form action="02.php" method="post">
<!-- action表示的是提交的后台地址,method代表的是提交的方式时get还是post -->
账号:<input type="text" value="提交内容"><br>
密码:<input type="password" ><br>
<input type="submit" value="提交">
</form>
</body>
在HTML的DOM中,设置submit()事件,通过为按钮或其它元素同样可以触发表单提交的事件
<body>
<form id="user" action="02.php" method="post">
账号:<input type="text" value="请输入账号"><br>
密码:<input type="password" value="请输入密码"><br>
重置:<input type="reset" value="重置"><br>
<button id="btn">提交</button>
</form>
<script>
var btnObj=document.getElementById("btn"),
formObj=document.forms[0];//forms表示获取页面中所有的表单,返回一个数组
btn.onclick=function(){
formObj.submit();
console.log("提交成功")
}
</script>
</body>
通过from表单提交数据不需要依赖js引擎,浏览器本身就可以实现,但这样也会产生一个问题,用户提交数据信息的时候需要刷新整个页面,这就大大降低了用户体验
Ajax
什么是Ajax
Ajax的诞生解决了上述的问题,Ajax代表的是:Asynchronous Javascript And XML,也就是异步,javascript和XML,Ajax不是一门编程语言,而是一种用于创建更好更快交互性更强的web应用技术,可以通过少量的浏览器和服务器 之间的数据交互实现页面的部分刷新,需要注意的是在使用了Ajax技术后,用户的请求数据是间接通过Ajax引擎来发出的,而不是直接通过浏览器来发出,服务器返回的数据也是传回到Ajax引擎
需要注意的是Ajax虽然在使用时的优点显而易见,但同时缺点也是有的:
- 对搜索引擎不友好
- 用户无法使用回退获得之前的页面
我们可以对比一下传统的提交方式和使用Ajax技术的提交方式的不同:
我们来举一个栗子:表单验证
Ajax引擎
Ajax的精华部分就是它的Ajax引擎,那么什么是Ajax引擎呢?就是XMLHttpRequest对象,除了已经入土的IE5,其它现代浏览器都支持该对象,同时它也是一个JavaScript对象,它负责发出请求和接收响应
在IE5和IE6中Ajax引擎是ActiveXRequest,所以我们需要做兼容性问题
<script>
function createAjax(){
var xhr;
window.XMLHttpRequest?xhr=new XMLHttpRequest():xhr=new ActiveXObject("Msxml2.XMLHTTP");
return xhr;
}
</script>
使用Ajax
创建Ajax引擎
也就是XMLHttpRequest对象,做兼容性判断
<script>
function createRequst() {
return window.XMLHttpRequest ? new window.XMLHttpRequest() :
new window.ActiveXObject('Microsoft.XMLHTTP');
}
console.log(createRequst());//在IE7-中返回的是一个object对象
</script>
XMLHttpRequest对象的方法和属性
我们找几个比较主要的说一下,
onloadstart 请求开始时触发的事件
onloadend 请求结束时触发的事件
ontimeout 请求超时时触发的事件
onreadystatechange 请求状态改变时触发的事件
readyState 请求状态
status 服务器返回的状态码
timeout 设置请求的时间,当请求的时间超过我们设置的时间时,自动将请求注销掉
withCredentials 是否要求证书(例如12306)
-
responseText 在非XML格式下返回的数据
建立连接
举一个栗子:
<script>
var xhr=createRequst();//封装的函数
xhr.open("GET","data.php",true);//如果是使用GET方式提交数据那么需要在URl后添加?然后把键值对之间以&符号 链接拼接在?后面,如果是使用POST获取数据,那么我们要将参数传递到send中,键值对与键值对之间使用&符号拼接
</script>
在建立连接时,我们要调用open方法,open方法有三个参数
open(type,url,isAsync),这几个参数分别代表:
- type,请求方式,GET还是POST,当然还有其它方式,如DELETE,用来删除服务器上的数据,但不常用,这里不列举了
- url ,请求的服务器的地址
- isAsync ,请求是否异步,默认为true,也就是异步请求
GET和POST
这里我们需要了解一下同样是请求后台数据,GET和POST的区别,在之前我们会想到的是:
- GET请求是体现在url地址栏中的,安全性比较差,POST是在request body提交的,安全性较高
- GET请求的参数是会被保存在地址栏中的,而POST不会,也就是说在我们使用后退键时,使用GET请求会保存在地址栏中
- 使用POST的时候,如果使用后退键会重复提交,而GET则不会
- POST方式理论上是没有大小的限制的,而GET方式由于浏览器会限制地址栏的长度,一般限制为2K字符以内,4K大小以内,超过部分不予解析
- 对于参数类型,GET方式只支持ASCLL编码格式,而POST则没有限制(使用前最好将传入的数据进行编码转换)
但是,在看到一篇大神的文章之后,以上的区别统统显的不重要了,我们来开始学习怎样高逼格的说明这俩者的不同
我们都知道,无论是GET还是POST请求,都是建立在HTTP协议之上的,而HTTP协议又是建立在TCP协议之上的,也就是HTTP协议规定的数据在万维网中传输的的规定,那么说白了GET和POST只是两种不同的TCP链接,只是由于浏览器的规定设置导致了有一些差异,在本质上并没有什么区别,实际上真正的差别在于,GET和POST在传输数据的过程中,GET会产生一个TCP数据包,而POST会产生两个数据包
浏览器在发送GET请求时是将http header和data一起发出,服务响应200,而在发送POST请求时。浏览器会先发送http header,服务器响应100 continue,再发送data,服务器响应200,也就是说,GET方式提交数据是一次性的,而POST第一次先告诉服务器我要请求数据,第二次再将数据提交过去
所以这里由于POST是两次请求,耗时会增加,这也是雅虎优化建议中为什么提出,我们尽量将页面中使用POST的方式改为GET来提升响应速度,但是,在网络性能好的情况下,使用GET和POST的时间差别几乎没有,在网络较差的情况下,两次打包会大大提升数据的完整性,而且不是所有浏览器都是两次打包的,FF就是使用一次打包
GET和POST同样不安全,通过POST加密的数据会被抓包工具截取,或者在F12中Network中Headers中获取,如果有要求使用加密同样需要通过加密方式进行加密
监听状态信息
继续上面的栗子:
<script>
xhr.onreadystatechange=function(){
if(xhr.readyState===4){//判断请求状态是否是已经完成
if(xhr.status>=200&&xhr.status<=300||xhr.status===304){//判断服务器是否返回成功200,304
console.log(xhr.responseText);//接收xhr的数据,xhr.responseText
}
}
}
</script>
这里有一些需要我们了解的东西
-
readyState 请求的状态码
0: 表示请求未初始化,也就是没有建立open请求
1: 表示建立open()请求,正在发送请求
2: 表示请求已经接收,open()方法已经完成,已经收到全部响应内容
3: 表示请求处理中,正在解析响应内容
4: 表示请求已经完成,响应也已经就绪,也就是说响应内容已经解析完成,可以在客户端进行调用了
-
status 服务器返回的状态码,有几种常见的类型:
以1开头代表请求已经接受
以2开头代表请求已经成功
- 200,请求成功
以3开头代表网页重定向,常见的几个:
- 304,代表浏览器缓存可以继续使用,服务器没有返回数据,直接从浏览器中获取数据
以4开头代表请求错误 ,检查是不是url输入错误或者是后台人员接口给错了
- 404,无法找到指定的资源,也就是url地址错误
- 405,请求方法对请求资源不适用
- 403,请求不允许
以5开头代表服务器错误,处理方法,直接通知后台人员,让他们进行处理
如何解决服务器返回304
浏览器有默认的缓存机制,在第一次向服务器请求数据的时候,在发现页面中存在文件请求时会发出请求,并将这些请求缓存在本地,在第二次向服务器发送请求的时候,在请求头中发送一个Last- Modified,它包含了上一次从服务器获得数据的日期。如果服务器判断从这个日期起服务器中数据没有进行修改,那么直接返回304的状态,不再重新发送数据,此时用户仅仅是获取了304状态码,不会再次请求数据,而是直接从本地读取缓存
最简单的方法就是直接在url地址中添加一个随机数的时间戳,例如:/Home/GetMusic?id=1+时间戳
在前端有个设置可以解决读取缓存的方法,设置meta标签的属性
<meta http-equiv="prgma" content="no-cache">
设置Ajax默认禁止缓存
<script>
var xhr=createRequst();//封装的函数
xhr.open("GET","data.php",true);
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<=300||xhr.status===304){
console.log(xhr.responseText);
}
}
}
xhr.setRequsetHeader("Content-type":"application/x-www-form-urlcoded");
xhr.setRequsetHeader("Canhe-Control","no-cache");//阻止浏览器读取缓存
xhr.send();
</script>
在JQ中设置Ajax的cache属性,参数为Bollean属性,默认为ture,设置为false
发送请求头
在使用POST发送页面的时候需要注意的是,要发送请求头,格式如下:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//设置请求头格式为仿照form表单提交
在发送Ajax请求时默认发送的请求头格式为文本格式,如果用来提交表单数据会报错,所以需要我们认为的设置请求头格式,以上的代码的作用就是告诉服务器我们发送的是form表单格式的数据
发送请求
<script>
//继续上面的代码
xhr.send();
</script>
这里我们注意一个问题,关于send()的位置问题,之前我们一直把send()放在监听事件状态之前,这样写在默认的异步状态下是没有问题的,但如果是在同步的状态下看,是会报错的,这就涉及到了执行顺序的问题,我们是需要先准备好怎么样接收数据,然后才能对数据进行接收
JSON数据
json是一种键值对模式的字符串,其中的键和值都是用双引号进行包裹,由于json的轻量和便于使用,现在大部分公司使用的都是json格式的数据,我们可以举几个例子来看一下
例如:
var str={"name":"Tom","age",18}//如果值是数字的话可以不使用双引号包裹
我们之前写对象的时候有时候会写如下的格式:
var obj={
"name":"tom",
"age":18
}
但需要注意的是,这种格式输出的仍然是对象,在js进行解析的时候,其中的键的双引号会被去除
我们来看一个比较复杂的json格式
var people =
{
"name":"Tom",
"programmers": [
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" },
{ "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }
]
}
JSON的方法
在浏览器中为我们提供了两种json数据格式转化的方法
JSON.parse(ison),该方法表示将接收到的json数据格式转化为对象格式,需要重点注意的是在使用JSON方法时,必须是键值对使用双引号包裹,所以外层的需要是单引号
JSON.stringify(obj),该方法表示将js中的对象转化为json格式的字符串
-
这里其实还有一个方法可以解析json格式的字符串,eval(),这个方法比较特殊,W3C对它的介绍是,很强大的一个功能,但是运用的很少,这是因为eval()方法本身会自动执行字符串中的方法,如果我们直接接收没有验证过的返回信息就会很容易遭到攻击,例如:
<script> var str={"name":alert("弹出")}; var o=eval(str); //在执行上述代码时会自动弹出alert提示框,因为在使用eval时已经执行了字符串内部的逻辑代码 </script>
JQuery中的Ajax使用
在JQuery中对Ajax方法进行了封装,JQuery的Ajax封装是非常强大的,在其他框架也大量借鉴了该方法,下面我们来看一下在JQuery中是如何使用Ajax的
比较简单方法:
<script>
$(function(){
$("#btn").on("click",function(){
$.post("02.php",{name:"Tom",age:18},function(data){
console.log(data)
},'json')
})
})
//相对应的还有GET和getJSON等其它方法,基本套路都一样
</script>
下面的是我们经常用到的,同样也是在其他框架中被参考的方法$.ajax
<script>
$.ajax({
type:"get",//设置请求的方式
url:"02.php",//设置请求的地址
data:{name:"tom",age:18},//设置发送的参数
dataType:"json",//请求的数据类型,自动转化为对象
async:true,//设置是否异步,默认为true
cache:false,//设置浏览器是否缓存该页面,默认为true
timeout:300,//设置请求超时时间
beforeSend:function(xhr){//请求开始前回调该函数
console.log("请求开始前");
//return false 如果在请求开始前直接return等于阻止了ajax请求
},
success:function(result,status){//请求成功时回调该函数,,result代表返回的数据,status为状态描述
console.log("请求成功了");
},
error:function(xhr,status,error){//请求失败时回调该函数,xhr为 XMLHttpRequest对象,status为错误信息,error表示捕获的错误对象
console.log("请求失败,"+xhr.status);
}
})
//以上只是我们常用的一些方法和参数,JQuery中还封装了很多其它的方法和参数,包括上面提到的$.get和$.post等方法都是该方法的变种
</script>
Ajax的封装
我们过这里模拟JQuery中的Ajax方法,对其进行简单的封装,不多说,直接上代码
<script>
function formatData(data) {//格式化数据的方法
var ret=[];
for(var key in data){
//有时候传入的可能是汉字,所以需要利用encodeURIComponent转化成编码格式
//encode方法废弃了,现在提供的是encodeURLConponent方法
ret.push(encodeURIComponent(key)+"="+encodeURIComponent(data[key]));
}
//伪造不同url,防止获取缓存的数据(http状态码304)xhr
ret.push(("="+new Date().getTime()))
return ret.join("&");
}
function createRequst(){//创建Ajax引擎对象
return XMLHttpRequest()?new XMLHttpRequest():new ActiveXObject("Msxml2.XMLHTTP")
}
function jsonp(option){
//判断用户传入的参数
if(!option||!option.url||!option.callback){
console.error("参数异常");
return;
}
//如果用户参数传入正确,创建script标签,添加到head标签中
var scriptElement=document.createElement("script"),
headElement=document.getElementsByTagName("head")[0];
headElement.appendChild(scriptElement);
//注意jsonp创建的函数是全局函数,为了防止代码污染,起特定的名字
var fnName=("jsonp_"+Math.random()).replace(".","");
option.data[option.callback]=fnName;//给用户传入的向后台发送的data数据中添加一个option.callback属性,并赋值为我们自定义创建的函数名,让后台接收我们的函数名,后台才能返回给我们数据
window[fnName]=function(data){
if(option.timeout){//用户如果设置了超时时间,在接收到数据后将计时器清除
window.clearTimeout(scriptElem.timer);
}
delete window[fnName];//删除全局函数
headElement.removeChild(scriptElem);//删除创建的script标签
option.success && option.success(data);
}
if(option.timeout){//如果用户设置了超时时间,设置计时器,在用户设置的超时时间到达后如果该函数执行,说明超时,那么执行其中的代码
scriptElement.timeout=window.setTimeout(function(){
delete global[fnName];
headElem.removeChild(scriptElem);
option.fail && option.fail({"message": "请求超时"});
}, option.timeout)
}
scriptElem.src = option.url + '?' + formatData(option.data);//执行跨域请求,跨域的时候不需要其它参数,所以data中的数据就是callback和它的值
}
}
$.extend({
AjaxSetting:{//设置用户默认输入的各项参数
url:"",
type:"GET",
dataType:"json",
async:true,
success:null,//成功后执行的函数
fail:null,//失败后执行的的函数
contentType:"application/x-www-form-urlencoded;charset=UTF-8"//模拟表单提交的请求头
},
ajax:function(url,option){//在JQuery中使用的两个参数,这里仿照JQuery写法
var context,xhr;
if(typeof url==="object") {//判断url类型,如果用户直接传入一个对象,说明没有单独传入URL地址,那么我们执行下面的代码
option=url;
url=null;
}else{//如果用户单独传入了url地址,那么我们执行下面的代码
option.url=url;
url=undefined;
}
if(!option||!option.url||!option.success){//判断用户是否输入option,option中的url和success是我们设置为默认必须的,所以在用户传入时就进行判断
console.error("参数传入异常");
return ;
//如果用户传入的参数异常,那么我们弹出异常,并且直接返回
}
// 通过JQuery中的extend方法获取默认设置
$.extend($.AjaxSetting, context);
// 通过JQuery中的extend方法获取用户设置,覆盖或新增默认的设置
$.extend(option, context);
if(context.dataType.toLowerCase()==="jsonp"){//判断用户是否要求跨域
jsonp(context);//如果是的话执行jsonp的方法
}else{//否则的话执行Ajax函数
xhr=createRequst();//通过createReqyst方法执行函数
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300||xhr.status==304){
var data=context.dataType.toLowerCase()=="json"?
JSON.parse(xhr.responseText):
xhr.responseText;
//判断用户需求什么格式的数据,如果是json的数据,将请求来的数据进行转换
context.success&&context.success(data,context,xhr);
//判断用户是否输入了success方法,如果有的话执行success方法,如果我们直接执行的 话,由于上面设置了success为null,用户如果没有设定会报错
}
}else{
context.fail && context.fail({"message": "请求超时."})
}
}
if(context.type.toUpperCase()=="GET"){
xhr.open("GET",context.url+"?"+formatData(context.data),context.async);
//利用formatData方法格式化数据
xhr.send();
}else{
xhr.open("POST",context.url,context.async);
xhr.setRequestHeader("contentType",context.contentType)
xhr.send(formatData(context.data));
}
}
}
})
</script>
Ajax轮询和长连接
Ajax轮询和长连接都是为了实现页面的实时刷新,但是需要注意,如果在不是必要的情况下尽量不要使用这两种方法,大量的不间断的数据请求对前台和后台都是非常有压力的
-
Ajax轮询
客户端定时向服务器发送Ajax请求,服务器在返回数据后断开连接,轮询能够实现页面的实时刷新,但是缺点也很明显,定时的发送数据大部分是没有意义的,而且占用额外的服务器资源
<script> function Ajax(){ setInterval(function(){ var xhr=new XMLHttpRequest(); xhr.open("open","url",true); xhr.onreadystatechange=function(){ if(xhr.readyState===4){ if(xhr.status>=200&&xhr.status<=300||xhr.status==304){ console.log(xhr.responseText) } } }; xhr.setRequestHeader("Content-type","qpplication/x-www-form-urlencoded"); },5000) } </script>
代码实际上很简单,就是调用计时器,每过一段时间向后台发送一次请求
-
long-polling
所以为了能够使页面及时刷新,并且改善轮询存在的弊端,我们一般使用的是长轮询的方法,也就是ling-poling
<script> $(function(){ (function longPolling(){ $.ajax({ url:"01.php", type:"get", datatype:"json", timeout:5000, error:function(xml,status,eror){ //可以选择报请求超时的错误,不过一般不这么做 longPolling(); }, success:function(data,status,xhr){ console.log(data); //如果有数据返回,那么将数据添加到页面 longPolling(); } }) })() }) </script>
Ajax长轮询需要后台写相应的代码来配合完成
模板引擎
什么是模板引擎,说白了就是在字符串中有几个变量待定
例如:
//这里用到的是attTemplate模板引擎
<script type="text/template" id='template01'>//为了防止script对内容进行解析,将script的type属性变为非javascript即可,改为template主要是为了增加代码的可读性
<tr>
<td><%=name%></td> //<%= %>代表输出值
<td><%=skill%></td>//在这里<%= %>中的skill代表的就是我们设定的待定的变量
<td><%=wife%></td>
<td>
<% for(var i=0;i<friends.length;i++){ %> // <% %>里的内容代表的是输出的逻辑语句
<a><%=friends[i]%></a>
<% }%>
</td>
</tr>
</script>
我们可以在写一个完整的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="js/template-native.js"></script>//导入模板引擎js文件
<script type="text/template" id="template">
<% for(var i = 0;i < posts.length; i++) {%>
<% var post = posts[i]; %>
<% if(!post.expert){ %>
<span>post is null</span>
<% } else { %>
<a href="#"><%= post.expert %> at <%= post.time %></a>
<% } %>
<% } %>
</script>
</head>
<body>
<script>
var data = {
"posts": [{
"expert": "content 1",
"time": "yesterday"
},{
"expert": "content 2",
"time": "today"
},{
"expert": "content 3",
"time": "tomorrow"
},{
"expert": "",
"time": "eee"
}]
};
var str=template('template',data);//artTemplate模板引擎的使用就是调用template方法,传入模板的id和变量的值
console.log(str)
</script>
</body>
</html>
封装方法主要是使用了string的方法和正则进行匹配,下面写一下大概的封装
<script>
function template(templateStr,data){//传入两个值,templateStr代表模板的字符串,data代表传入的变量对象
var reg = /<%=\s*([^%>]+\S)\s*%>/,//定义正则匹配<%= %>
result;
while(result=reg.exec(templateStr)){//根据正则的exec方法的属性如果没有符合的返回null来确定循坏停止的条件
var matchString=result[0],//根据exec方法返回的是<%= %>这部分的字符串
matchWord=result[1];//根据exec方法返回的是<%= %>中的字符,也就是我们传入的data中的键
templateStr=templateStr.replace(matchString,data[matchWord]);
//调用字符串的rplace方法,符合的目标进行替换
}
return templateStr;
}
</script>
跨域
什么是跨域
处于安全性的考量,现代所有的浏览器都遵循同源策略,同源策略不允许Ajax获取其它页面的数据,我们通过某种方式来获取其它网页的数据的方式就是跨域
同源策略
简单来说就是在两个网页域名,端口,协议任意不同的情况下,A网页无法获取B网页的数据,举一个例子来说明:
http://www.example.com/dir/page.html
http://www.example.com/dir2/other.html //同源
http://example.com/dir/other.html //不同源,域名不同
http://v2.www.example.com/dir/other.html //不同源,域名不同
http://www.example.com:81/dir/other.html //不同源,端口不同
注意,同一域名下的不同服务器获取数据也是跨域,例如两台电脑的IP地址不同,A不能直接获取B电脑服务器的数据
如果是非同源那么会受到以下限制:
cookie, localStorage和indexDB无法读取
DOM无法获取
-
AJAX请求可以发送,但是无法获取响应
跨域的方式
单向数据请求
JSONP
什么是JSONP,很多人会把jsonp和Ajax搞混,或者认为jsonp是Ajax提供的跨域方法,但特别需要注意,这两者是相互独立的
jsonp的本质可以认为是src属性是不受同源策略的限制,可以获取其它域的数据,利用src能够跨域获取数据的特性来实现我们从其它的网站获取数据,但是必须是在该网站配合的前提条件下
实际在之前的很多操作中我们已经使用到了src能够跨域的这个特性,例如我们在img中插入一张图片,可以直接把图片的地址复制到src中
<img src="https://www.baidu.com/img/bd_logo1.png">
下面我们来举一个jsonP跨域的例子:
<script type="text/javascript" src='http://192.168.18.38/2016-8-22/coding/cross/05.jsonP.php?callBack=sayhi'>
</script>
<script type="text/javascript">
function sayhi(data) {//参数data就是我们要获取的跨域的数据,在拿到之后可以配合模板引擎在页面中放置
console.log(data);//sayHi方法会自执行,因为在后台传送数据时会用括号将callback的值包裹起来
}
//后台在接收到callBack后,湖区到sayhi的名称,返回sayhi(”(“+data+”)“);所以我们接收的函数的参数就是我们要获取的数据
</script>
在JQ中为我们封装了跨域的方法,有两种方式:
1.$.ajax()方法
<script type="text/javascript">
$(function(){
$.ajax({
url:"http://api.map.baidu.com/telematics/v3/weather?location=北京 &output=json&ak=tq0Kt0NFYheTCj5mszast0drkIqqVTNn",
dataType:"jsonp",//只需要将dataType设置为jsonp即可
success:function(data){
console.log(data)
}
})
})
</script>
需要注意的是,src这个属性实际上是等同于发送了一个GET形式的Ajax请求,包括href,所以我们在页面中尽量不要写空的href和src属性,可以减小服务器的压力
jsonp实际上就是我们手动创建script,然后再script中引用某一个js文件
2.getJson方式
<script type="text/javascript">
$.getJson('http://csdn.net/blog/data.java?callback=?',function(data){console.log(data)//处理返回的数据});
</script>
window.name
在一个window的存活周期下,窗口载入的所有页面都共享一个window.name属性,每个页面都对它有可读可写的权限,即使window.location重载也不会有变化
window.name的格式为字符串,更多的时候我们使用json的格式来进行书写,window.name存在字符串的限制,最大的大小为2M
下面我们来举一个栗子:
a.html
<body>
<input type="button" id="btn" value="点击">
<script>
window.name="这是a网页设置的";
document.getElementById("btn").onclick=function(){
window.location.href="b.html"
}
</script>
</body>
b.html
<body>
<script>
console.log(window.name);//"这是a网页设置的"
</script>
</body>
双向数据请求
window.postMessage
这个方法和window.name一样,需要是同一个页面打开的窗口
我们直接来举一个栗子:
//数据端发送
<script>
//弹出一个新窗口
var myPopup = window.open(domain
+ '/windowPostMessageListener.html','myWindow');
//周期性的发送消息
setInterval(function(){
var message = 'Hello! The time is: ' + (new Date().getTime());
var domain = 'http://scriptandstyle.com';
console.log('blog.local: sending message: ' + message);
myPopup.postMessage(message,domain);
//postMessage有两个参数1.message代表的是要发送的数据
// 2.domain代表的是要发送数据到哪个地址
},6000);
</script>
//数据端接收
<script>
//响应事件
window.addEventListener('message',function(event) {
if(event.origin !== 'http://davidwalsh.name') return;
console.log('message received: ' + event.data,event);
event.source.postMessage('holla back youngin!',event.origin);
},false);
//需要注意的是1.需要对浏览器进行判断,众所周知IE使用的是attachEvent
//这里注意message是postMessage的接收事件,其中有三个参数1.source,代表消息源,也就是发送消息的窗口
//2.origin,代表消息源的url,包含协议,端口,域名,用来验 证数据源
//3.data,发送方发送过来的数据
</script>
后台转换
这个方法是实际工作中最常用的,我们如果有需要跨域请求数据,一般会让后台配合请求到数据然后在返回给前台使用