• 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;
        }

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

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

  • 相关阅读:
    根据snort规则写openvas nasl 攻击 脚本
    snort规则中tcp/udp端口的具体作用
    snort规则头解析
    正则匹配中的特殊案例
    snort 规则 byte_test 不同运算符命中条件
    Linux中tar命令的一些用法
    Thymeleaf传递url参数
    PO BO VO DTO POJO DAO DO 令人迷惑的Java概念
    linux中多个命令连接符— ; && || ()
    遇见了count(1)这种写法,什么意思?
  • 原文地址:https://www.cnblogs.com/fengxiaoqing/p/5380857.html
Copyright © 2020-2023  润新知