webqq的注册登记和聊天页面--运用jsonp跨域

简介:

我们知道,ajax用于数据交互,但它不能跨域,跨域是指从一个域名的网页去请求另一个域名的资源。比如从http://www.baidu.com/ 页面去请求  的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域。也就是说如果一家公司的官网有了改革,以前的官网网址和新的都可以访问,由于域名有稍微的改变,那么自己公司的官网就不能跳转到自己的另一个官网信息,这显然是很不方便的,于是jsonp就出场了,由它来解决这个问题。今天笔者从一个项目出发,来分析jsonp的具体用法。

webqq项目:

我们先来布局下注册登录页面:

<div id="login_box">
    用户名:<input id="user" type="text" value="欧巴" /> <br /><br />&nbsp;码:<input id="pass" type="text" value="123" /><br /><br />
    <input id="login" type="button" value="登陆" />
    <input id="reg" type="button" value="注册" />
    
</div>

加上样式

*{ margin:0; padding:0; list-style:none; font-family: "微软雅黑","张海山锐线体简"}

body{ text-align:center;}
#login_box{width:300px; padding:10px; border:1px solid #000; margin:100px auto;}

 

然后封装好一个json函数,这个函数中,url,data,success,error,cbKey,timeout这六个参数是可选项,url就是就是公司给你的那个php地址,data就是我们之后要的用户名,密码,头像等等等等数据;sucsess函数就是当我们jsonp请求成功,会调用的函数;error就是jsonp请求失败要调用的函数;cbKey代表回调回调函数;timeout做延迟用的,如果在指定的延迟时间内没有完成相应的指令,服务器就会告诉网页就不要在等了,直接调用加载错误的那个函数吧!而这些参数有时全用的到,有时只用到部分,于是我们用参数options来代表它们,以便使用。

我们有关jsonp的代码都放在function json(opations){}中,在这个函数里,我们先整理好options:

options = options||{};
if(!options.url) return;
options.data=options.data||{};
options.success=options.success||null;
options.error=options.error||null;
options.cbKey=options.cbKey||'cb';
options.timeout=options.timeout||0;

 

下面来一步步写这个写回调函数

首先,我们要先把必要的食材都准备好:

var cbValue    =    'jsonp'+Math.random();

你们懂的,之所以加上Math这个方法,是为了保证函数名随机,以便每次刷新的函数都不同。

 

为了防止因这个回调函数的函数名出现.而引发错误,我们用过replace将它替代掉,就是看到.就把它去掉

options.data[options.cbKey]=cbValue.replace('.','');

 

然后我们先做好这个函数,已备后来调用

window[options.data[options.cbKey]]=function(json){
        
        clearInterval(timer);
        
        options.success && options.success(json);
    
        document.getElementsByTagName('head')[0].removeChild(oScript);
        window[options.data[options.cbKey]]=null;
    };

这是jsonp请求成功要调用的函数,为了保持每次刷新后的script引用都不一样及性能优化,我们要删掉script标签,即把不用的标签拿掉,src前脚链入,后脚拿掉,但是如果这个间隔里出现了状况,比如中间网断了不就挂了,于是我们需src成功时再拿掉,要在函数调用后再删掉。

 

然后要做url的相关处理了:

var arr=[];
for(var key in options.data){
        arr.push(key+'='+encodeURIComponent(options.data[key]));    
}
    
options.url = options.url+'?'+arr.join('&')

先声明个空数组,然后通过encodeURIComponent把字符串作为URI 组件进行编码,把编码后的push进准备好的空数组里,最后把这个数组再用&把各段分开变成字符串。这里的知识点就是数据类型转换。

 

var oScript=document.createElement('script');
    oScript.src=options.url;
    document.getElementsByTagName('head')[0].appendChild(oScript);

这一步就是创建script标签,并把它放入页面,知识点就是DOM操作。

 

if(options.timeout){
        var timer=setTimeout(function(){
            options.error&& options.error();
            window[options.data[options.cbKey]]=function(){
                       };    
        },options.timeout);    
}        

这是延迟后调用的error函数。

至此我们的jsonp函数就封装完毕了!!

 

关于cookie

下面我们开聊聊cookie,他的主要作用是保存信息,用来登录时记住用户名等,两个页面传数据,

主要的特点:①不能跨域,

      ②存储空间很小,4k左右

      ③一个域名只有一套cookie

      ④不安全,所以不要存隐私哦

      ⑤有效期过后,隐私无法保证

当然cookie的特点不止这些,由于本重点在jsonp上,因此关于cookie笔者只在此粗略的介绍,有时间一定再做更为细致的研究,现在把关于coookie的封装函数直接附上:

function removeCookie(name){
    setCookie(name,'',-1);
}

function getCookie(name){
    //alert(document.cookie);    
    var arr=document.cookie.split('; ');
    for(var i=0;i<arr.length;i++){
        var arr2=arr[i].split('=');    
        if(name==arr2[0]){
            return arr2[1];
        }
    }
    return '';
}

function setCookie(name,value,timeout){
    var d=new Date();
    d.setDate(d.getDate()+timeout)
    document.cookie= name+'='+value+';expires='+d;    
}

下面我们来直接在我们之前页面布局的那个html文档里来对这个登录页面进行编辑吧:

首先引入jsonp函数,我们把它存在一个jsonp.js的文件里吧,然后再引入有关cookie的函数,我们把这个存cookie的文件取名cookie.js,引入的代码如下:

<script src="cookie.js"></script>
<script src="jsonp.js"></script>

然后我们开始核心的javascript操作吧

抓取对象:

var oReg=document.getElementById('reg');
var oLogin=document.getElementById('login');
var oUser=document.getElementById('user');
var oPass=document.getElementById('pass');

 

下面是url地址,大家根据公司给的php接口链入就可以了

下面是注册的编辑,达到预期的效果就是当用户名和密码输入后点击注册,如果这个用户名未被注册过,就弹出注册成功,然后点击登录,就可进入聊天界面;如果这个用户名被注册过,则弹出用户名已备占用,然后重复上面操作,下面来用javascript实现

注册部分:

这时候要找公司给的相应的的注册部分的接口,形如:?a=reg&user=用户名&pass=密码&face=头像ID&cb=xxx

代码演示如下:

oReg.onclick=function(){
        //?a=reg&user=用户名&pass=密码&face=头像ID&cb=xxx
        jsonp({
            url:    url,
            data:    {
                a:    'reg',
                user:oUser.value,
                pass:oPass.value,
                face:1+Math.random()*(8-1)    
            },
            success:function(json){
                //{err: 0, msg: "注册成功"}
                alert(json.msg);
                if(json.err==0){
                    alert(json.msg);    
                }else{
                    alert(json.msg);    
                }
            }
        });    
    };

登录部分的代码演示如下:

oLogin.onclick=function(){
        //?a=lgn&user=用户名&pass=密码&cb=xxx
        jsonp({
            url:    url,
            data:    {
                a:    'lgn',
                user: oUser.value,
                pass: oPass.value    
            },
            success:function(json){
                //    {err: 0, msg: "登录成功", face: 头像ID, login_time: 上次登录时间, token: "token"}
                if(json.err==0){
                    //跳转页面
                    //alert(json.token);//{13666022-D398-D647-70E2-2C247768EF04}
                    setCookie('token',json.token,1);//存cookie
                    setCookie('username',oUser.value,1);//存cookie
                    window.location.href='chart.html'    
                }
            }
        });    
    };

至此,注册登录的页面已经完工!

当输入正确的用户名和密码后,点击登录,就进入了聊天页面,下面开始聊天页面的的编辑。

首先先写好布局:

<div id="div1">
    <div id="left">
        <input type="button" id="exit" value="注销">
        <div id="content">
            <!--<dl>
                <dt><span>昵称</span>   <strong>时间</strong></dt>
                <dd>聊天内容</dd>
            </dl>-->
        </div>
        <div id="input_box">
            <textarea id="txt1"></textarea>
            <input id="btn_send" type="button" value="发送" />
            
        </div>
    </div>
    <ul id="right">
       <!--<li><img src="images/face/1.jpg" />昵称</li>-->
    </ul>
</div>

然后是给它加上样式:

*{ margin:0; padding:0; list-style:none; font-family: "微软雅黑","张海山锐线体简"}

#div1{ position: absolute;width:100%; height:99%;}
#left{ position:absolute;left:0;top:0;width:79%; height:100%; -background:yellow;}
#content{position:absolute;left:0;top:0;width:100%; height:79%; -background:pink;overflow-x:hidden;overflow-y:auto;}
#content dl{border-bottom:1px dashed #999; margin-bottom:0.2em;}
#content dl dt span{ font-size: 16px; font-weight:bold;}
#content dl dt strong{ font-weight:normal; font-size:12px;color:#999;}
#content dl dd{ padding-left:2em;font-size: 14px;}
#input_box{position:absolute;left:0;bottom:0;width:100%; height:20%; background:#ccc;border-top:10px solid #000;}
#input_box textarea{width:100%; height:100%; border:none; resize:none;}
#exit{position:absolute;right:5%; top:5%; padding:10px; font-weight:bold; z-index:99999999;}
#btn_send{ position:absolute;right:5%; bottom:30%; padding:10px; font-weight:bold;}

#right{ position:absolute;right:0;top:0;width:20%; height:100%; border-left:10px solid #000; background:green;
    overflow-x:hidden;overflow-y:auto;

}
#right li{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;margin: 2px;
  background: #eee;padding:5px;}/* 文字超出显示省略号*/
#right li img{width:40px;vertical-align:middle;margin-right:20px;}

和编辑注册登录页面一样加入jsonp和cookie对应的js文件:

<script src="cookie.js"></script>
<script src="jsonp.js"></script>

核心javascript部分编,每次的jsonp调用时,要参照公司给的相关接口,根据接口来写,具体编辑如下:

先抓取对象:

var oBtnSend=document.getElementById('btn_send');
var oTxt=document.getElementById('txt1');
var oContent=document.getElementById('content');
var oRight=document.getElementById('right');
var oExit=document.getElementById('exit');
    
var url='http://zhinengshe.com/exercise/im/api.php';
    
var toKenContent=getCookie('token');
var username=getCookie('username');

然后写发言部分:

oBtnSend.onclick=function(){
        //?a=snd_msg&content=内容&token=&cb=xxx
        jsonp({
            url:    url,
            data:    {
                a:    'snd_msg',
                content:    oTxt.value,
                token:    toKenContent    //取cookie
            },
            success:function(json){
                //{err: 0, time: 发布时间, ID: 消息ID}
                json.content=oTxt.value;
                json.username=username;    //取cookie
                //{err: 0, time: 发布时间, ID: 消息ID,content:xxx,username:xxx}
                createDl(json);
                oTxt.value='';
            }
        })    
    };    
jsonp({
        url:    url,
        data:    {
            a:    'get_msg',
            token:    toKenContent
        },
        success:function(json){
            //    {err: 0, data: [{ID: 消息ID, post_time: 消息时间,content: 消息内容,username: 发言用户},...]}
            if(json.err==0){
                var arr=json.data;
                for(var i=0;i<arr.length;i++){
                    createDl(arr[i]);    
                }    
            }
        }
    });

获取用户列表:

jsonp({
        url:    url,
        data:    {
            a:    'get_user_list',
            token:    toKenContent
        },
        success:function(json){
            //{err: 0, data: [{ID: 用户ID,username: 用户名,face: 用户头像}]}
            
            if(json.err==0){
                var arr=json.data;
                for(var i=0;i<arr.length;i++){
                    var oLi=document.createElement('li');
                    
                    if(arr[i].face<1) arr[i].face=1;
                    if(arr[i].face>8) arr[i].face=8;
                    
                    oLi.innerHTML='<img src="images/face/'+arr[i].face+'.jpg" />'+arr[i].username;
                    oRight.appendChild(oLi);
                }    
            }
            
            
        }
    });

下面是注销:

//?a=logout&token=&cb=xxx
    oExit.onclick=function(){
        jsonp({
            url:    url,
            data:    {
                a:    'logout',
                token:    toKenContent,
            },
            success:function(json){
                //{err: 0, msg: "成功退出登录"}
                if(json.err==0){
                    window.location.href='login.html';
                }else{
                    alert('网断了')    
                }
            }    
        });    
    };

获取更新:

//?a=get_msg_n&n=消息ID&token=&cb=xxx
    var lastId=0;
    setInterval(updatMsg,1000);
    function updatMsg(){
        //console.log('请求:',lastId);
        jsonp({
            url:    url,
            data:    {
                a:    'get_msg_n',
                n:    lastId,//请求新信息的起始点
                token:toKenContent
            },
            success:function(json){
                //{err: 0, data: [{ID:'1',post_time:'1364873875',content:'asdfsdf',face:'1',username:'test',to:'发给谁'},...]}    
                if(json.err==0){
                    var arr=json.data;
                    for(var i=0;i<arr.length;i++){
                        createDl(arr[i]);    
                    }
                }
            }    
        });        
    }
function createDl(json){
        //{err: 0, time: 发布时间, ID: 消息ID,content:xxx,username:xxx}发言后返回的数据
        //{ID: 消息ID, post_time: 消息时间,content: 消息内容,username: 发言用户}获取所有信息返回的
                //{ID:'101',post_time:'1364873875',content:'asdfsdf',face:'1',username:'test',to:'发给谁'}实时更新返回的    
        
        lastId=json.ID;
        //console.log('更新:',lastId)
                    
        //整理返回的时间
        var time=json.time||json.post_time;
        
        var oDl=document.createElement('dl');
        
        var d=new Date();
        d.setTime(time*1000)
        oDl.innerHTML=
                '<dt><span>'+json.username+'</span>   <strong>'+d+'</strong></dt>\
                <dd>'+json.content+'</dd>';
        oContent.appendChild(oDl);
        
        //控制滚动条
        //oContent.scrollTop=oContent.scrollHeight-oContent.offsetHeight;
        oContent.scrollTop=oContent.scrollHeight;
    }

到这里聊天的界面就完工了!

以上就是我分享的内容,有欠妥的地方,敬请指正。

 

posted @ 2016-04-12 00:45  DaisyF  阅读(732)  评论(0编辑  收藏  举报