• 【应用】信息短时存储


    功能

    这是一个在线的应用(这里是地址),用来短时间存储一些信息,以实现在不同设备上共享这些信息的功能。其实目的就是可以将手机上的一些信息快速的复制到电脑上,尤其是在使用Linux系统的时候。下面是该应用的截图。其中阅后即焚是指信息被访问一次之后就会被销毁。
    应用界面

    流程

    程序主要的流程就是首先在文本框中输入或者粘贴一些内容,然后保存到服务器(使用的是新浪sae),保存成功之后会返回给客户端一个编号,通过该编号就可以访问存储的内容。因为就是为了给手机和电脑之间的复制粘贴提供一个介质,所以信息的有效时间暂时设为了2分钟,2分钟之后就会清除保存的信息。

    前端实现

    整体风格

    程序使用的是bootstrap框架,如果你还没有用过这个前端框架,那么强烈推荐你试用一下,因为使用该框架可以极大的减少你的工作量,并且兼容手机设备。下面是页面的主要html代码,其中css样式几乎全部为bootstrap定义的样式,这样我们就可以将更多的时间放在功能实现,而不是网页设计上。

    <div class="container ">
        <div class="row ">
            <div style="padding:10px; ">
                <form class="bs-example bs-example-form" role="form">
                    <div class="col-lg-12">
                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">编号</span>
                            <input type="text" class="form-control" id="textId">
                                <span class="input-group-btn">
                                    <button class="btn btn-default" type="button" id="msgGet">获取信息</button>
                               </span>
                        </div>
    
                        <br>
    
                        <div class="form-group ">
                            <textarea class="form-control custom-control change_font" style="resize:none" rows="8"
                                      placeholder="请输入信息" id="mainText"></textarea>
    
                        </div>
                        <div class="text-center">
                            <button type="button" class="btn btn-primary button_width" id="msgClear">清空</button>
                            <button type="button" class="btn btn-primary button_width2 " id="msgSave">保存</button>
                            <div class="bootstrap-switch ">
                                <input type="checkbox" name="onlyOne" data-label-text="阅后即焚" data-on-text="是"
                                       data-off-text="否" onSwitchChange="changeOne">
                            </div>
                        </div>
                    </div>
    
                </form>
            </div>
        </div>
    </div>
    

    bootstrap有自适应机制,页面内容的宽度会随浏览器窗口的大小改变而改变。但是在我们的页面中如果采用默认的自适应机制,就可能会造成在较宽的屏幕上输入框的宽度过大,从而使的页面看起来不美观。所以我们更改了一下其默认行为,当浏览器窗口宽度大于800px时,将网页内容的宽度固定为800px。实现方式很简单,加上下面的css代码即可。

    @media screen and (min- 800px) {
        .container {
             800px;
        }
    }
    

    还有一点就是input的placeholder属性在较低的IE版本中不兼容,使用下面的js代码可以解决这个问题

    var JPlaceHolder = {
        //检测
        _check: function () {
            return 'placeholder' in document.createElement('input');
        },
        //初始化
        init: function () {
            if (!this._check()) {
                this.fix();
            }
        },
        //修复
        fix: function () {
            jQuery(':input[placeholder]').each(function (index, element) {
                var self = $(this), txt = self.attr('placeholder');
                self.wrap($('<div></div>').css({position: 'relative', zoom: '1', border: 'none', background: 'none', padding: 'none', margin: 'none'}));
                var pos = self.position(), h = self.outerHeight(true), paddingleft = self.css('padding-left');
                var holder = $('<span></span>').text(txt).css({position: 'absolute', left: pos.left, top: pos.top, height: h, lienHeight: h, paddingLeft: paddingleft, fontSize: '1.5em', color: '#aaa'}).appendTo(self.parent());
                self.focusin(function (e) {
                    holder.hide();
                }).focusout(function (e) {
                    if (!self.val()) {
                        holder.show();
                    }
                });
                holder.click(function (e) {
                    holder.hide();
                    self.focus();
                });
            });
        }
    };
    //执行
    jQuery(function () {
        JPlaceHolder.init();
    });
    

    bootstrap开关切换插件

    在选择"阅后即焚"功能的地方,我们使用了一个开关切换的插件——bootstrap switch,这里 是该插件的github地址,使用起来也十分简单,下面是一个简单的示例,更多的属性可以参考官方文档

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <title>bootstrap switch demo</title>
        <link rel="stylesheet" href="css/bootstrap3/bootstrap.min.css">
        <link rel="stylesheet" href="css/bootstrap3/bootstrap-switch.min.css">
    
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
        <script type="text/javascript" src="js/bootstrap-switch.min.js"></script>
    
        <script type="text/javascript">
            $(document).ready(function() {
                $("[name='my-checkbox']").bootstrapSwitch();
    
                $('input[name="my-checkbox"]').on('switchChange.bootstrapSwitch', function(event, state) {
                    console.log(this); // DOM element
                    console.log(event); // jQuery event
                    console.log(state); // true | false
                });
            });
        </script>
    </head>
    <body>
    
    <input type="checkbox" name="my-checkbox" data-on-text="是" data-off-text="否" checked>
    
    </body>
    </html>
    

    效果图如下所示

    信息提示

    一般来说使用alert就可以实现弹窗提示的功能,但是各个浏览器的弹窗样式都不相同并且也不美观,这里使用了jQuery Toaster插件,效果如下图所示,这里 是github地址。

    这个插件需要bootstrap 3.0+,不过使用起来更加方便,只需要引入一个jquery.toaster.js即可,下面是一个示例

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <title>bootstrap toaster demo</title>
        <link rel="stylesheet" href="css/bootstrap3/bootstrap.min.css">
    
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
        <script type="text/javascript" src="js/jquery.toaster.js"></script>
    
    </head>
    <body>
    <div>
        <button id="open" class="btn btn-primary ">Click Me</button>
    </div>
    
    <script type="text/javascript">
        $("#open").click(function () {
           $.toaster({message: 'Your message here', title: 'Your Title', priority: 'danger'});
        })
    </script>
    </body>
    </html>
    

    在默认情况下,弹窗出现的位置是在右上角,我们可以修改一下css样式使其出现在屏幕中间,不过要首先去jquery.toaster.js中,将下面的代码注释掉(大概90行附近),

    'css'       :
    {
         'position' : 'fixed',
         'top'      : '10px',
         'right'    : '10px',
         'width'    : '300px',
         'zIndex'   : 50000
    }
    

    下面是修改后的代码:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <title>bootstrap toaster demo</title>
        <link rel="stylesheet" href="css/bootstrap3/bootstrap.min.css">
    
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
        <script type="text/javascript" src="js/jquery.toaster.js"></script>
        <style type="text/css">
            @media screen and (min- 800px) {
                .center_toaster {
                    right: 30%;
                     40%;
                }
            }
    
            @media screen and (min- 500px) and (max- 799px) {
                .center_toaster {
                    right: 20%;
                     60%;
                }
            }
    
            @media screen and (min- 200px ) and (max- 499px) {
                .center_toaster {
                    right: 5%;
                     90%;
                }
            }
        </style>
    </head>
    <body>
    <div>
        <button id="open" class="btn btn-primary ">Click Me</button>
    </div>
    
    <script type="text/javascript">
    
        $.toaster({
            settings: {
                'toaster': {
                    'class': 'center_toaster',
                    'css': {
                        'position': 'fixed',
                        'top': '2px',
                        'zIndex': 50000
                    }
                }
            }
        });
        $("#open").click(function () {
            $.toaster({message: 'Your222 message here', title: 'Your Title', priority: 'danger'});
        })
    </script>
    </body>
    </html>
    

    不过按上面修改之后在低于IE9的浏览器中工作并不理想,可能是IE9以下对 @media 支持不太好,所以在js的代码中加了一个判断,如果浏览器支持html5的一些特性(使用jquery判断)就使用toaster,否则使用alert。

    if ($.support.leadingWhitespace) {
        $.toaster({ priority: 'warning', title: '警告', message: '编号不能为空'});
    } else {
        alert("警告:编号不能为空");
    }
    

    Loading插件

    当用户点完获取数据或者保存按钮时,会弹出一个正在加载的弹出层,防止由于网络延迟等原因造成用户重复点击,下面是效果图

    这里 是github地址。下面是一个简单的示例:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <title>bootstrap watingDialog demo</title>
        <link rel="stylesheet" href="css/bootstrap3/bootstrap.min.css">
    
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
        <script type="text/javascript" src="js/bootstrap-waitingfor.js"></script>
    
    </head>
    <body>
    <div>
        <button id="open" class="btn btn-primary ">Click Me</button>
    </div>
    
    <script type="text/javascript">
        $("#open").click(function () {
            waitingDialog.show();
    
            setTimeout(function() {
                waitingDialog.hide();
            },2000);
        })
    </script>
    </body>
    </html>
    

    底部固定

    当页面内容的高度小于屏幕的高度时,将footer固定在底部,当页面内容的高度大于屏幕高度时,footer会随着滚动条滚动,不会遮盖到正常的内容,下面一个解决方法,这里 是原文地址。

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <title>bootstrap fixed footer demo</title>
        <link rel="stylesheet" href="css/bootstrap3/bootstrap.min.css">
    
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
    
        <style type="text/css">
            * {
                margin: 0;
            }
    
            html, body {
                height: 100%;
            }
    
            .wrapper {
                min-height: 100%;
                height: auto !important;
                height: 100%;
                margin: 0 auto -6em;
            }
    
            /*push和footer的高度不一样是因为加了一条hr*/
            .push {
                height: 6em;
            }
    
            .footer, {
                height: 4em;
            }
        </style>
    </head>
    <body>
    
    <div class="wrapper">
        <div class="container">
            <p>这里是内容</p>
        </div>
        <div class="push"></div>
    </div>
    
    <footer class="footer">
        <div class=" col-lg-12 text-center">
            <hr>
            <p>Copyright &copy; zhangjk 2015</p>
        </div>
    </footer>
    
    </body>
    </html>
    

    服务端实现

    平台及语言

    服务器使用的新浪的sae,语言是使用的php。

    php restful service

    因为应用逻辑非常简单,就是一个存和取数据,所以简单的实现了几个restful的接口,并没有使用专门的框架(主要是对php不熟悉)。接口的实现参考自__这篇文章__,下面是该文章给出的代码:

    <?php
    /*
    	API Demo
    
    	This script provides a RESTful API interface for a web application
    
    	Input:
    
    		$_GET['format'] = [ json | html | xml ]
    		$_GET['method'] = []
    
    	Output: A formatted HTTP response
    
    	Author: Mark Roland
    
    	History:
    		11/13/2012 - Created
    
    */
    
    // --- Step 1: Initialize variables and functions
    
    /**
     * Deliver HTTP Response
     * @param string $format The desired HTTP response content type: [json, html, xml]
     * @param string $api_response The desired HTTP response data
     * @return void
     **/
    function deliver_response($format, $api_response){
    
    	// Define HTTP responses
    	$http_response_code = array(
    		200 => 'OK',
    		400 => 'Bad Request',
    		401 => 'Unauthorized',
    		403 => 'Forbidden',
    		404 => 'Not Found'
    	);
    
    	// Set HTTP Response
    	header('HTTP/1.1 '.$api_response['status'].' '.$http_response_code[ $api_response['status'] ]);
    
    	// Process different content types
    	if( strcasecmp($format,'json') == 0 ){
    
    		// Set HTTP Response Content Type
    		header('Content-Type: application/json; charset=utf-8');
    
    		// Format data into a JSON response
    		$json_response = json_encode($api_response);
    
    		// Deliver formatted data
    		echo $json_response;
    
    	}elseif( strcasecmp($format,'xml') == 0 ){
    
    		// Set HTTP Response Content Type
    		header('Content-Type: application/xml; charset=utf-8');
    
    		// Format data into an XML response (This is only good at handling string data, not arrays)
    		$xml_response = '<?xml version="1.0" encoding="UTF-8"?>'."
    ".
    			'<response>'."
    ".
    			"	".'<code>'.$api_response['code'].'</code>'."
    ".
    			"	".'<data>'.$api_response['data'].'</data>'."
    ".
    			'</response>';
    
    		// Deliver formatted data
    		echo $xml_response;
    
    	}else{
    
    		// Set HTTP Response Content Type (This is only good at handling string data, not arrays)
    		header('Content-Type: text/html; charset=utf-8');
    
    		// Deliver formatted data
    		echo $api_response['data'];
    
    	}
    
    	// End script process
    	exit;
    
    }
    
    // Define whether an HTTPS connection is required
    $HTTPS_required = FALSE;
    
    // Define whether user authentication is required
    $authentication_required = FALSE;
    
    // Define API response codes and their related HTTP response
    $api_response_code = array(
    	0 => array('HTTP Response' => 400, 'Message' => 'Unknown Error'),
    	1 => array('HTTP Response' => 200, 'Message' => 'Success'),
    	2 => array('HTTP Response' => 403, 'Message' => 'HTTPS Required'),
    	3 => array('HTTP Response' => 401, 'Message' => 'Authentication Required'),
    	4 => array('HTTP Response' => 401, 'Message' => 'Authentication Failed'),
    	5 => array('HTTP Response' => 404, 'Message' => 'Invalid Request'),
    	6 => array('HTTP Response' => 400, 'Message' => 'Invalid Response Format')
    );
    
    // Set default HTTP response of 'ok'
    $response['code'] = 0;
    $response['status'] = 404;
    $response['data'] = NULL;
    
    // --- Step 2: Authorization
    
    // Optionally require connections to be made via HTTPS
    if( $HTTPS_required && $_SERVER['HTTPS'] != 'on' ){
    	$response['code'] = 2;
    	$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
    	$response['data'] = $api_response_code[ $response['code'] ]['Message'];
    
    	// Return Response to browser. This will exit the script.
    	deliver_response($_GET['format'], $response);
    }
    
    // Optionally require user authentication
    if( $authentication_required ){
    
    	if( empty($_POST['username']) || empty($_POST['password']) ){
    		$response['code'] = 3;
    		$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
    		$response['data'] = $api_response_code[ $response['code'] ]['Message'];
    
    		// Return Response to browser
    		deliver_response($_GET['format'], $response);
    
    	}
    
    	// Return an error response if user fails authentication. This is a very simplistic example
    	// that should be modified for security in a production environment
    	elseif( $_POST['username'] != 'foo' && $_POST['password'] != 'bar' ){
    		$response['code'] = 4;
    		$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
    		$response['data'] = $api_response_code[ $response['code'] ]['Message'];
    
    		// Return Response to browser
    		deliver_response($_GET['format'], $response);
    
    	}
    
    }
    
    // --- Step 3: Process Request
    
    // Method A: Say Hello to the API
    if( strcasecmp($_GET['method'],'hello') == 0){
    	$response['code'] = 1;
    	$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
    	$response['data'] = 'Hello World';
    }
    
    // --- Step 4: Deliver Response
    
    // Return Response to browser
    deliver_response($_GET['format'], $response);
    
    ?>
    

    对于apache服务器,需要修改一下.htaccess文件,该成下面的形式

    # Turn on the rewrite engine
    Options +FollowSymlinks
    RewriteEngine on
     
    # Request routing
    RewriteRule ^([a-zA-Z_-]*).(html|json|xml)?$   index.php?method=$1&format=$2 [nc,qsa]
    

    其中RewriteRule部分是指将[a-zA-Z_-]*匹配到的字符串赋值到 $1 的位置,将(html|json|xml)?匹配的字符串赋值到 $2 的位置,访问 hello.json 就相当于访问 index.php?method=hello&format=json
    在sae中,使用的服务器也是apache,不过它不能更改.htaccess文件,而是需要修改config.yaml文件,如果使用git方式管理代码,默认是不会将该文件下载到本地的,所以推荐使用svn方式管理代码,下面是具体配置

    name: appname
    version: 1
    
    handle:
      -rewrite: if(!is_dir() && !is_file() && path ~ "^([a-zA-Z_-]*).(html|json|xml)?$") goto "index.php?method=$1&format=$2"
    

    信息存储--memcache

    这里存储没有使用数据库,而是使用的memcache,主要是信息只是短期存储,并且数据量不会太大。官方对memcache的使用解释的并不是十分详细,这里主要参考了 这篇文章 ,下面是具体的代码:

    <?php
        //连接
        $mem = memcache_init();
        
        //保存数据
        $mem->set('key1', 'This is first value', 0, 60);
        $val = $mem->get('key1');
        echo "Get key1 value: " . $val . "<br />";
        
        //替换数据
        $mem->replace('key1', 'This is replace value', 0, 60);
        $val = $mem->get('key1');
        echo "Get key1 value: " . $val . "<br />";
        
        //保存数组
        $arr = array('aaa', 'bbb', 'ccc', 'ddd');
        $mem->set('key2', $arr, 0, 60);
        $val2 = $mem->get('key2');
        echo "Get key2 value: ";
        print_r($val2);
        echo "<br />";
        
        //删除数据
        $mem->delete('key1');
        $val = $mem->get('key1');
        echo "Get key1 value: " . $val . "<br />";
        
        //清除所有数据
        $mem->flush();
        $val2 = $mem->get('key2');
        echo "Get key2 value: ";
        print_r($val2);
        echo "<br />";
        
        //关闭连接
        $mem->close();
        
    

    其中$mem->set的第四个参数就是数据的有效期,单位是秒。

    ajax跨域访问

    为了使服务端允许客户端的ajax跨域请求,需要在php代码中加上下面的代码。

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

    前端使用jquery 的 $.ajax 发送ajax请求,在IE10及以上的版本中,工作正常,但是IE9及以下的版本无法正确访问,找了半天也没有找到好的解决方法。索性就在sae上放了一个同样的应用首页,如果使用IE9及以下的浏览器,可以访问那个页面。

  • 相关阅读:
    增删改查, SQL语句,注意事项
    形参
    接收前台的GET/POST请求
    数据库能查出数据,但mybatis查询出返回的结果是null
    resultType
    日期和字符串互转、数据库处理日期
    ajax的简单应用
    设置
    深度解密Go语言之unsafe
    golang中,map作为函数参数是如何传递的
  • 原文地址:https://www.cnblogs.com/zhangjk1993/p/5035190.html
Copyright © 2020-2023  润新知