AJAX2

第五章*****************************************************************************************

AJAX处理数据格式application/javascript

问题: 一般.js文件中,script请求(任何人)(任何时间)js内容都一样

解决: 在服务器端返回"动态js",根据客户端不同或访问时间不同,js也不同

服务器端:

header("Content-Type:application/javascript;charset=utf-8");

echo "var msg = '你好';alert(msg);";                  //msg随情景不同发生改变

客户端:

eval(xhr.responseText);                  //执行php中写的js程序

_______________________________________________________________________________________________

跨域访问(Cross Domain Request)

浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如JavaScript)对不同域(协议、子域名、主域名protocal、端口port、主机host)的服务进行跨站调用

跨域定义:

① 两个域名不同  a.com → b.com

② 协议名不同    http://... → https://...

③ 主机名/IP不同 http://127.0.0.1/1.php → http://localhost/2.php

④ 端口号不同    http://127.0.0.1:80/1.php → http://127.0.0.1:8080/2.php

⑤ 子域名不同    1.a.com → 2.a.com

浏览器允许跨域请求的情形: img src="..." / link href="..." / script src="..." / iframe

浏览器默认禁止XHR(ajax)跨域访问(同级目录下除外)———可能会导致外来的数据对当前程序影响,造成数据安全风险

注意: 跨域并不是请求发不出去,而是请求能发出去,服务端能收到请求并正常返回结果,但结果被浏览器拦截了

三种行为会受到跨域限制:

① cookie、localStorage、indexDB

   当一级域名相同,二级域名不同时,可设置相同的document.domain共享cookie

② DOM无法获得

③ ajax请求无法获得

方式一 JSONP

解决方案: JSONP JSON with Padding(填充式JSON)是一种使用JSON数据的方法,用于解决浏览器xhr跨域请求限制

jsonp思路:

发起异步请求时不使用'ajax对象xhr',而是使用一个动态创建的 script 标签代替xhr:

  <script async src="跨域访问x.php"></script>        //async:异步

步骤:

① 客户端:

方法1:  创建标签→设置属性→追加在head中

btn.onclick = function(){

  var script=document.createElement("script");

  script.src="http://127.0.0.1/kuayu/async.php";

  script.async=true;                    //异步请求属性

  document.head.appendChild(script);    //创建一个script标签,并追加到head中

}

或者:

<script>

function doResponse(data){

  console.log(jsondata);    //处理获得的json数据

}

</script>

<script src="http://127.0.0.1:8090?doResponse=?"></script>

方法2:  使用dataType:"jsonp"//jsonp只能是 'GET' 形式,不要写POST,可能会报错

        jQuery封装好的方法1,会在head开头插入script标签,响应成功后移除

$.ajax({

url:'http://127.0.0.1/web1703/day08/06_jsonp.php',

dataType:"jsonp",//使用JSONP形式调用函数,标志跨域请求

jsonp:'jsonp_callback',//跨域函数名的键值(服务器提取函数名的钥匙,默认为callback)

jsonpCallback:'doRespons',//客户端与服务端约定的函数名,取代jQuery自动生成的随机函数名

                              //若服务器已设置jsonp属性,则不需要再设置此属性(此值用来替代GET或POST请求中URL参数里的"callback=?"部分,并传给服务器)

  success:function(res){},    //若设置jsonpCallback属性,则执行success函数,不执行error函数

                              //否则相反

  error:function(err){}

});

② 创建函数,接收参数(设置jsonpCallback后可省略)

function doResponse(res){     //创建函数,用来接收服务器响应数据data

  console.log(res);

}

③ 服务器:

<?php

header("Content-Type:application/javascript;charset=utf-8");    //向客户端发送js程序

$json='{"ename":"tom"}';

echo 'doResponse('.$json.');';        //拼接json字符串,js函数收到的参数就是这个json字符串

?>                                      //客户端接收:doResponse(json),会执行这个函数

node中

res.end("callback("+str+")");    //发送的函数名要与ajax的jsonpCallback的值一致

                                 //这个函数callback可不写,会自动接着执行ajax的success函数

jQuery中的jsonp类型,会创建一个查询字符串参数callback=?,这个参数会加在请求的URL后面,服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求

如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp参数

当从服务器接收到数据时,实际上是用了&lt;script&gt;标签而不是XMLHttpRequest对象,$.ajax()不再返回一个XMLHttpRequest对象,并且也不会传递事件处理函数,比如beforeSend

方式二 CORS

jsonp只能是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择

方法:

后台直接开启同源策略的访问限制,在允许被跨域访问的文件头部加上:

header("Access-Control-Allow-Origin:*");

或者:header("Access-Control-Allow-Origin:http://localhost:63342端口号");

可限制请求方式: header("Access-Control-Allow-Methods:POST,GET");

CORS需要浏览器和服务器同时支持。目前IE浏览器中IE10及以上才可正常发送请求,其它浏览器都支持

CORS是W3C中一项较新的方案,所以部分浏览器还没有对其进行支持或者完美支持

CORS在移动终端支持的不错,可以考虑在移动端全面尝试;PC上有不兼容和没有完美支持,所以小心踩坑

浏览器将CORS请求分成两类:  简单请求(simple request)和非简单请求(not-so-simple request)

只要同时满足以下两大条件,就属于简单请求:

① 请求方法是这三种方法之一:  HEAD、GET、POST

② HTTP的头信息不超出这几种字段:  Accept、Accept-Language、Content-Language、Last-Event-ID

   Content-Type只限于三个值:  application/x-www-form-urlencoded

                              multipart/form-data        text/plain

凡是不同时满足上面两个条件,就属于非简单请求

对于简单请求,浏览器直接发出CORS请求。就是在头信息之中,增加一个Origin字段

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json

CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 Ajax 请求。实现此功能只需由服务器发送一个响应标头即可

① 客户端 (与正常请求一致):

btn.onclick = function(){

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function (){

    if (xhr.readyState === 4 & xhr.status === 200){

      var obj=JSON.parse(xhr.responseText);           //将后台相应的数据转换成对象

      console.log(obj);

    }

  }

  xhr.open("GET", "http://127.0.0.1/z_review/jsonp/cors.php", true);

  xhr.send(null);

}

② 服务器端:

<?php

header("Access-Control-Allow-Origin:*");             //比正常响应多一个此字段

header("Access-Control-Allow-Origin: http://localhost:63342");   //或者只允许特定网址访问

header("Content-Type:application/json;charset=utf-8");    //若不加此段会返回字符串

                                                          //加上之后会返回一个对象

$json='{"ename":"tom"}';

echo  $json;

?>

Node.js中使用CORS跨域:

①服务器端:

app.all("*",function(req,res,next){

 res.header("Access-Control-Allow-Origin:*");   //添加此字段

 res.header("Access-Control-Allow-Origin","http://localhost:63342");  //只允许特定网址访问

  next();

})

app.get("/kuayu",(req,res)=>{

  console.log(req);

  res.json({ename:"tom"});

})

② 客户端比同域请求的url多出ip及端口:

btn.onclick = function(){

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function (){

    if (xhr.readyState === 4 & xhr.status === 200){

      var obj=JSON.parse(xhr.responseText);        //将后台相应的数据转换成对象

      console.log(obj);

    }

  }

xhr.open("GET", "http://127.0.0.1:8080/kuayu", true);    //必须加http

  xhr.send(null);

}

方式三、通过修改document.domain来跨子域

方式四、使用window.name来进行跨域

方式五、使用HTML5中新引进的window.postMessage方法来跨域传送数据(IE 6/7 不支持)

方式六、nginx反向代理

方式七、使用WebSocket

第六章*****************************************************************************************

XML(java 旧项目)

html: 超文本标记语言,所有标签预定义好:  h1、h2用于描述一个网页结构

xml: 可扩展的标签语言,所有标签都是自定义的,用于描述一段数据,尤其是复合数据

xml语法:  XML和HTML用途不同,xml语法更加严格

① xml文档类型声明

<?xml version="1.0" encoding="utf-8"?>

② 整遍xml有且只有一个根元素,比如:  <books></books>

③ 标签有开始必须有结束,开始标签与结束的标签完全相同:  <book></book>

④ 标签可以嵌套不能交叉:  <book><id><i></i></id></book>是正确的

⑤ 标签可以有任意属性

服务器端: 通过程序xml文档并且发送

<?php

header("Content-Type:application/xml;charset=utf-8");

echo "<?xml version='1.0' encoding='utf-8'?>";

echo "<根元素>";                 //在php中输出时,必须用单引号或双引号括起来

echo "<name>......</name>";

echo "</根元素>";

?>

客户端:

使用DOM操作原生AJAX发送请求xml数据

btn1.onclick=function(){

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange=function(){

    if(xhr.readyState===4&&xhr.status===200){

      var doc=xhr.responseXML;

    }

  }

  xhr.open('get','xml.php',true);

  xhr.send(null);

}

使用jQuery操作AJAX发送请求数据

btn2.onclick=function(){

  $.ajax({

    type:"get",

    url:"xml.php",

   dataType:"xml",           //指定服务器返回类型

    success:function(data){...}

  });

}

处理XML数据的方法:

① data.documentElement.getElementsByTagName("row")        //使用原生DOM访问XML数据

② $(data).find("row")                                     //使用jQuery访问XML数据

可以使用操作DOM的方式访问XML的标签、属性、值

   $(res).find("p").each(function(){ console.log($(this).attr('id')) })

第七章*****************************************************************************************

Cookie

作用: 保存(指定保存时间)用户添加的数据,默认情况会话结束数据就删除了(一般是服务器使用)

会话: 是一个操作过程,当用户打开浏览器请求指定页面(会话开始),进行操作,最后关闭浏览器(会话结束)

特点:

① 可以自动在浏览器端和服务器端来回传递,存储量约4k,所以不要将不必要的数据放到Cookie中

② 可以设置过期时间,超出时间后,自动消失

操作方式

① 保存数据至cookie(保存cookie的页面):

document.cookie='uid='+uid;

document.cookie="uname="+uname;            //不会覆盖除uname的值

② 从cookie中获取数据(调用cookie的页面):

var cookieArray=document.cookie.split("; ");

var cookieObj={};

  for(var i=0;i<cookieArray.length;i++){

    var sub=cookieArray[i].split("=");

    var key=sub[0];

    var val=sub[1];

    cookieObj[key]=val;

  }

if(!cookieObj.uid){

  location.href="输入cookie内容的页面";

}

修改cookie过期时间

var now = new Date();

now.setFullYear(now.getFullYear()+1);

设置为一年后过期:

document.cookie = 'answer='+JSON.stringify(cookieObj.answer)+'; expires='+now.toGMTString();

设置为永远不过期:

document.cookie = 'answer='+JSON.stringify(cookieObj.answer)+'; expires=Fri, 31 Dec 9999 23:59:59 GMT';

设置cookie路径: document.cookie = "name=value; path=/";

注意事项: cookie数据保存在客户端浏览器中,不要将安全性高数据保存在cookie

cookie保存数据通常是: 用户编号/用户喜欢产品编号/昵称

XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入javascript脚本,为了减轻这些攻击,需要在HTTP头部配上set-cookie:

httponly  这个属性可以防止XSS,它会禁止javascript脚本来访问cookie

secure    这个属性告诉浏览器仅在请求为https的时候发送cookie

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容