AJAX2

作者: fastwe | 来源:发表于2018-11-28 21:21 被阅读0次

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

    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

    相关文章

      网友评论

          本文标题:AJAX2

          本文链接:https://www.haomeiwen.com/subject/hjpbqqtx.html