Ajax

  Ajax(Asychronus javascript + XML),是Garret命名的一种技术实现,可以让页面无刷新即可从服务器取得数据。

  在Ajax技术流行前,如果你有留意过,在我们点击表单提交按钮后,表单开始提交,然后页面跳转刷新页面,并在新页面上显示请求结果。但如网络不稳定或者其他状况时,你可能会经历漫长的等待并最终收获一个404页面,用户体验并不友好。而Ajax这一技术能够向服务器请求额外的数据而无需卸载页面,改变了Web长久的"点击,等待"的交互模式,带来更好的用户体验。

  Ajax技术的核心是XMLHttpRequest对象(不一定是XML数据),为向服务器发送请求和解析服务器响应提供接口,能够以异步的方式获得新数据。

  1.XHR简单用法

  open(method,url,acceptAsychReq):调用此方法不会真正发送请求,只是启动一个请求准备。

  send(data)

  responseText

  responseXML

  status

  statusText

  readyState:  0:未初始化,不能调用open()  1:已经调用open(),但未调用send方法

         2:已经调用send(),但未接受到回应  3:接受部分数据  4:接受到全部数据

  abort:在readyState < 3时可以调用,终止请求.

  setRequestHeader:可自定义

  getResponseHeader

  getAllResponseHeader

 

// var xhr = new XMLHttpRequest();
var url = "https://translate.google.cn/";
xhr.onreadystatechange = function(){    //在调用open之前
    if(xhr.readyState == 4){
        if((xhr.status >=200 && xhr.status <= 300) || xhr.status == 304){
            console.log(xhr.responseText)
        }else{
            alert("Request was successful with" + xhr.status)
        }
    }
}
function addURLParam(url,name,value){
    url += (url.indexOf("?") == -1 ) ? "?" : "&";
    url += encodeURIComponent(name) +  "=" + encodeURIComponent(value);
    return url
}
var queryUrl = addURLParam(url,"name","lihua");
console.log(queryUrl);
xhr.open("get",queryUrl,true);
xhr.setRequestHeader("accept","text/plain");//必须设置在open后,send前
xhr.setRequestHeader("header","value") 
xhr.send(null);

 

  2.XMLHttpRequest 2级(常用)

  FormData(表单序列化)

  

//客户端
 <form id = "submit">
        <input type="text" name="name">
        <input type="text" name="age">
        <input type="radio" name="gender">male</input>
        <input type="radio" name="gender">female</input>
        <input type="submit" value="submit">
    </form>
    <script>
        document.getElementById('submit').onsubmit = function (e) {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status == 200 || xhr.status == 304) {
                        alert(xhr.responseText)
                    }
                }
            }
            xhr.open('post', '/dir', true);
            var form = document.forms[0]
            var data = new FormData(form);
            xhr.send(data);
            e.preventDefault();
        }
    </script>
//服务器端
//FormData的Content-type为multipart/form-data
var express = require('express');
var multer  = require('multer')
var upload = multer()
var app  = express();
 
app.post('/dir',upload.none(),function(req,res){
  res.send(req.body)
})

  跨域资源共享

  默认情况下,XHR对象只能访问包含它的页面位于同一个域的资源,防止某些恶意行为。但是合理的跨域请求也是非常重要的!

  CORS(cross orgin resource sharing)的基本思想,就是使用自定义的HTTP头部让浏览器与服务器沟通,从而决定是否响应是否应该成功!

  

//浏览器设置Origin头部
Orgin:http://www.myNet.com

//服务器回发相同资源信息
Access-Control-Allow-Origin:http://www.myNet.com
//如果没有回应头或者回应信息不匹配,浏览器就会驳回请求。特别的,COOKIE信息不被包含在头部内.

//IE对CROS的实现:XDR,功能于XHR类似,此处省略
//其他浏览器对CROS的实现
xhr.open("get", absolute URL,true(false));
//限制:1:不能发送COOKIE  2:不能设置头部  3:调用getAllResponse返回空字符串
//若需要COOKIE信息或者其他凭据信息:

withCredentials:true

//响应

Acess-Controll-Allow-Credentials:true

  

  其他跨域技术

  图像Ping:利用<img>可以从任何网页加载图像的特性,与服务器进行简单,单向的跨域交流。

  

var img = new Image();
img.onload = img.onerror = function(){
    alert("end")
}
img.src = "http://www.lihua.com/test?name=lihua"

 

  缺点:1:只能发送get请求  2:无法获取响应文本信息

 

  JSONP

  JSON是JSON with padding(填充式JSON)的简写,使用动态script元素,能够直接访问响应文本,支持在浏览器与服务器之间双向通信。它主要由两部分组成:回调数据和函数。

//客户端

function handleResponse(data){
            alert(data.name+':'+data.count);
  }
 var script = document.createElement('script');
 script.src = "http://localhost:3001/api/?callback=handleResponse"    
 document.body.insertBefore(script,document.body.firstChild;
//服务器
app.get('/api',function(req,res){
    var data = {
        count:"1",
        name:"lihua",
      }
    var dataJson = JSON.stringify(data)
    res.send('handleResponse'+'('+dataJson+')')
})

  缺点:1:安全性问题  2:确定JSONP请求失败不容易

 

  Comet

  Comet是Alex Russel发明的一个词,指的是一种更高级别的Ajax技术。Ajax是一种能够向服务器请求数据的技术,而Comet则是一种服务器向页面推送技术。实现方式有两种:长轮询(传统短轮询的翻版)和流。

  

  短轮询和长轮询都是要向服务器发送http请求,不同之处在于数据的响应。短轮询是服务器立刻发送数据,无论数据是否有效。而长轮询则一直保持连接打开,直到有数据可发送。

  流实现是http流,区别于轮询,它在整个生命周期只有一个http请求,然后服务器保持打开,周期性的向浏览器发送信息。流技术的实现关键是所有服务端语言都支持将缓存中的内容一次性全部发送的功能。

  

function getStreamingData(url,process,finished){
    var xhr = new XMLHttpRequest();
    var received = 0;
    xhr.open("get",url,true);
    xhr.onreadystatechange = function(){
        var result ;
        if(xhr.readyState == 3){
            result = xhr.responseText.substr(received);
            received += xhr.responseText.length;
            process(result)
        }else if(xhr.readyState == 4){
            finished(xhr.responseText)
        }
    }
    xhr.send(null);
    return xhr;
}

var text = getStreamingData("url",function(result){
    alert('Data:'+result)
},function(fullText){
    alert('fullText')
})

 

  服务器发送事件

  SSE(Server-sent Events)是围绕只读Comet交互推出的API,用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的必须MIME类型类型必须是text/event-stream,而且是浏览器的JS API能解析的格式。

  

var source = new EventSource("同源URL");
//open message error
//data:foo
//
//data:foo
//data:bar

//data:bar
//id:"bar"
//id可用last-Event-ID追踪
source.message = function(event){
    var data = event.data;
}

  Websocket

  以后再细讲!  

 

posted on 2019-09-23 00:22  zqannnnn  阅读(33)  评论(0编辑  收藏

统计