会话 Cookie和Session

会话 Cookie和Session

会话概述

BS结构的程序类似于打电话,从浏览器第一次访问服务器开始,服务器就创建了一个会话。整个过程中,浏览器不断地向服务器发送请求,服务器也不断向浏览器做出响应,这个过程就称为一个会话。当用户关闭浏览器的时候,这个会话就结束。

两种会话技术

有两种技术实现浏览器与服务器之间的会话:Cookie和Session

Creates a cookie, a small amount of information sent by a servlet to a Web browser, saved by the browser, and later sent back to the server. A cookie’s value can uniquely identify a client。

创建一个Cookie,通过Servlet发送给浏览器的少量的信息,保存在浏览器,然后再由浏览器发送回给服务器,一个Cookie的值能够唯一标识一个客户端。

格式:一个Cookie对象就是一个键值对,键和值都是字符串类型

image

原理:
1) 第一次浏览器访问服务器的时候,没有Cookie。
2) 由Servlet服务器创建Cookie,以响应头Set-Cookie的方式发送给浏览器。
3) 浏览器接收到Cookie以后,存储到浏览器端。
4) 后续再访问服务器,将Cookie的信息以请求头:Cookie的方式发送给服务器。


Cookie操作相关的方法

创建Cookie
- Cookie(String name,String value) 构造方法,没有无参的构造方法。键和值都是字符串类型
- String getName() 得到Cookie的名字
- String getValue() 得到Cookie的值

Cookie的写入响应方法:
- response.addCookie(cookie对象)
- 将Cookie对象返回给浏览器

示范:
//1. 创建Cookie
Cookie user = new Cookie("name", "NewBoy");

//2. 通过响应对象写入Cookie到浏览器
response.addCookie(user);

查询响应头Response Hears的显示:
Set-Cookie: name=NewBoy

Cookie的过期时间

默认是浏览器关闭以后,当前Cookie失效

image

方法:
- void setMaxAge(int expiry) 设置Cookie过期时间,单位是秒。

代码:

//1. 创建Cookie
Cookie user = new Cookie("name", "NewBoy");

//设置Cookie过期的时间
user.setMaxAge(60 * 10);

//2. 通过响应对象写入Cookie到浏览器
response.addCookie(user);

结果的到期时间:

image

Cookie的读取:

  • Cookie[] request.getCookies()

    • 读取浏览器端发送过来的所有的Cookie返回Cookie的数组

代码:

PrintWriter out = response.getWriter();

//1.读取Cookie,返回数组
Cookie[] cookies = request.getCookies();
//2. 先判断数组是否为空,如果没有Cookie返回null
if (cookies !=null) {
    //进行遍历操作
    for (Cookie cookie : cookies) {
        out.print("Cookie的名字:" + cookie.getName() + ", Cookie的值:" + cookie.getValue() + "<br/>");
    }
}
else {
    out.print("没有任何的Cookie");
}

out.close();

Cookie中使用汉字的情况

Cookie中不支持直接使用汉字,如果要使用汉字的话,需要进行URL编码。直接使用汉字报错

image

  • java.net.URLEncoder.encode(“字符串”,”utf-8”)
    • 对字符串进行URL编码
  • java.net.URLDecoder.decode(“字符串”,”utf-8”)
    • 对字符串进行URL解码

创建Cookie并把中文编码

Cookie user=new Cookie("name",URLEncoder.encode("你好","utf-8"));
response.addCookie(user);

获得所有的Cookie并把中文解码输出

Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
        writer.print("name: "+cookie.getName()+" | value: "+URLDecoder.decode(cookie.getValue(),"utf-8")+"<br/>");
    } 

设置Cookie的路径

设置路径的方法
Cookie设置路径的方法

  • cookie.setPath(路径);

    • 设置浏览器向服务器发送Cookie的访问路径

只有访问指定的路径或它的子路径,请求才将Cookie的信息发送给服务器

默认的路径
如果没有设置访问路径,默认是当前的项目访问路径
http://localhost:8080/项目名/

演示:创建一个Cookie,设置过期时间,设置Cookie的访问路径
Set-Cookie: name=Jack; Expires=Wed, 03-Jan-2018 02:18:14 GMT; Path=/aaa

问:

如果访问路径是setPath(“/day39-cookie”),以下路径哪些可以正常访问Cookie?

访问地址能否访问到Cookie
http://localhost:8080/day39-cookie/可以
http://localhost:8080/day39-cookie/aaa/bbb可以
http://localhost:8080/day39-aaa不可以
http://localhost:8080/不可以

Cookie的删除

  • cookie.setMaxAge()

    • 将过期的时间设置为0,表示删除Cookie
//删除指定的Cookie
Cookie visitedTime = new Cookie("visitedTime", "");

//删除Cookie,过期的时间设置为0
visitedTime.setMaxAge(0);

//写入到浏览器
response.addCookie(visitedTime);

案例

需求

1) 如果用户是第一次访问,则输出:您好,您是第1次访问,当前的时间是xxx
image
2) 把这次访问服务器的时间写到Cookie中

3) 如果之前已经访问过,则从Cookie中得到上次访问的时间,显示:您好,欢迎您再次访问。

上次访问的时间是:xxxx,当前的时间是xxxxx。
image

image
代码:
CookieUtils

public class CookieUtils {
/**
 * 从Cookie数组中取一个名字为name的值,如果有则返回值,没有则返回空。
 */

public static String getCookieValue(HttpServletRequest request , String name) {

    //1. 得到所有的Cookie
    Cookie[] cookies = request.getCookies();

    //2. 如果数组不为空,遍历数组
    if (cookies!=null) {
        for (Cookie cookie : cookies) {
            //3. 比较每个名字是否与name相等,如果相等返回它的值
            if (cookie.getName().equals(name)) {
                return cookie.getValue();
            }
        }
    }
    //没有找到
    return null;
    }
}

Servlet

 // 1) 得到当前时间
String time = new Timestamp(System.currentTimeMillis()).toString();
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();

// 2). 从Cookie中取一个叫visitedTime的信息,如果为null,则表示第一次访问
String value = CookieUtils.getCookieValue(request, "visitedTime");

if (value == null) {
    out.print("<h1>欢迎您的第1次访问,现在的时间是:" + time + "</h1>");
}

// 3). 否则读取Cookie的信息,并且显示上次访问的时间
else {
    out.print("<h2>欢迎再次访问,您上次访问的时间是:" + value + "</h2>");
    out.print("<h2>这次的时间是:" + time + "</h2>");
}

// 4). 无论上次访问时间是否为空,都把这次访问的时间写入Cookie中
Cookie cookie = new Cookie("visitedTime", time);

// 设置过期时间
cookie.setMaxAge(60 * 60 * 24 * 30 * 6);

// 写入浏览器
response.addCookie(cookie);

out.close();

HttpSession会话

Session技术的特点:

1) 数据保存在服务器的内存中,底层是一个Map对象
2) 每一个用户对应一个会话
3) 不同的会话之间数据不能共享的

Session和Cookie的主要区别在于:

1) Cookie的数据是存在浏览器端缓存中

2) Session的数据是存在服务器的内存中

HttpSession的使用


创建Session的注意事项

Hession session=request.getSession();

在获得会话时候,要注意会话是否过期(用户在页面停留太久没有操作),如果session过期再调用会话的方法会出错,因为过期了获得会话的时候是新创建一个session

所以转化成
- Hession session =request.getSession(true);
- Hession session =request.getSession(false);

getSession(boolean create)意思是返回当前reqeust中的HttpSession ,当create为true,就创建一个新的Session,否则当create为fasle时候,没有session时返回null;

简而言之:

  • HttpServletRequest.getSession(ture) 等同于 HttpServletRequest.getSession()

  • HttpServletRequest.getSession(false) 等同于 如果当前Session没有就为null


创建会话的时机:

用户第一次访问服务器,并且调用request.getSession()方法,创建一个会话对象HttpSession对象。如果当前会话没有,则创建一个,如果有则得到原有的会话对象。

HttpSession接口方法

  • String getId()

    • 得到当前会话的ID,每个会话都有一个唯一的ID,是一个32位的十六进制数不同的用户会话ID是不同的,不同的浏览器就是不同的用户
  • long getCreationTime()

    • 得到会话创建的时间,返回的是1970-1-1到创建时间相差的毫秒数
  • long getLastAccessedTime()

    • 得到会话最后访问的时间,上一次的访问时间
  • boolean isNew()

    • 判断是否是一个新的会话,新的会话返回true
  • ServletContext getServletContext()

    • 可以通过会话对象得到上下文对象

示范

//得到会话
HttpSession session = request.getSession();
out.print("您的会话ID是:" + session.getId() + "<br/>");
out.print("会话创建的时间:" + new Timestamp(session.getCreationTime()) + "<br/>");
out.print("上一次访问的时间:" + new Timestamp(session.getLastAccessedTime()) + "<br/>");
out.print("现在的时间:" + new Timestamp(System.currentTimeMillis()) + "<br/>");
out.print("是否是新的会话:" + session.isNew() + "<br/>");

image

分析原理

SetServlet:

// 向会话域中添加值
HttpSession session = request.getSession();
session.setAttribute("product", "洗衣机");

GetServlet:

//从会话域中取出值
HttpSession session = request.getSession();
out.print(session.getAttribute("product"));

HTTP协议是无状态协议,不能保存用户的状态信息。如何知道这是否是同一个用户呢?

  1. 查看SetServlet中的响应头:

    将会话的ID通过Cookie发送给浏览器,浏览器可以得到这个Cookie

    Set-Cookie: JSESSIONID=921E1BA691655F94D74C6E28345A4CE0; Path=/day39-session/; HttpOnly

2) 查看GetServlet的请求头:

`Cookie: JSESSIONID=921E1BA691655F94D74C6E28345A4CE0`

下次再访问的时候,将这个Cookie发送给服务器,服务器读取Cookie信息,和服务器中的会话ID进行比较,如果相等,表示是同一个用户。

可以理解服务器创建SessionID的时候,也创建了一个Cookie,然后把SessionID放进去Cookie然后一起响应给浏览器

```
//创建Cookie
Cookie cookie = new Cookie("JSESSIONID", session.getId());

//写到浏览器中
response.addCookie(cookie);
```

会话的原理分析:
image
1) 浏览器第1次服务器,服务器通过getSession()创建一个会话对象。并且分配一个会话ID。

2) 通过Set-Cookie,将JSESSIONID发送给浏览器。

3) 下次访问浏览器将Cookie发送给服务器,服务器得到会话ID,与所有的会话比较,找到它所对应会话。

4) 不同浏览器的ID是不同的。

5) 同一个浏览器关闭以后,Cookie过期,再次打开浏览器,得不到原来的会话ID。

HttpSession的分析

如果浏览器关闭,服务器上的会话信息是否还存在?

答:只要会话没有过期,服务器上的会话信息是存在。

原因:
为什么取不到原来的数据,因为会话ID丢失。所以不能得到原来的会话信息。

方案:
可以将会话ID写到Cookie中,设置Cookie的过期时间。
Set-Cookie:JSESSIONID=BD324DB78ED6E0BBBCBE11F4150EADAE; Path=/day39-session/; HttpOnly

Set-Cookie:JSESSIONID=BD324DB78ED6E0BBBCBE11F4150EADAE; Expires=Wed, 03-Jan-2018 04:42:12 GMT

代码:

public void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

    // 向会话域中添加值
    HttpSession session = request.getSession();

    //创建Cookie
    Cookie cookie = new Cookie("JSESSIONID", session.getId());

    //设置Cookie过期时间
    cookie.setMaxAge(60 * 60);

    //写到浏览器中
    response.addCookie(cookie);
    session.setAttribute("product", "洗衣机");

}
个人的话

不同浏览器有不同的会话Id 不同的Session,sessionID是基于Cookie发送给服务器的,一个浏览器关闭后或者Cookie关闭后,sessionID就会丢失,为了不让丢失可以设置Cookie的生命周期,但是太久也没用,因为服务器端也有sessionID的生命周期,默认1800秒,30分钟,

疑问:Session在服务器上默认的销毁时间是多久?如何查看?
  • session.getMaxInactiveInterval()

    • 最大非活动时间间隔,单位是秒。默认是30分钟

代码:

HttpSession session=request.getSession();
//获得服务器的生命周期
out.print("服务器会话过期的时间:"+session.getMaxInactiveInterval()+"秒");

结果:

image

改变会话的生命周期:

方式一:
  • session.setMaxInactiveInterval(秒)

    • 修改会话过期的时间,单位是秒

    在指定的时间内如果与服务器有交互,服务器就会重新计时。

代码

 // 输出会话过期的时间
HttpSession session = request.getSession();
out.print("是否新的会话:" + session.isNew() + "<br/>");
out.print("会话的ID:" + session.getId() + "<br/>");

//修改会话过期的时间
session.setMaxInactiveInterval(10);
out.print("服务器会话过期的时间:" + session.getMaxInactiveInterval() + "秒");

结果:
image

方式二:
  • 通过修改web.xml中配置,修改会话过期的时间
<!-- 修改会话过期的时间 -->
<session-config>
    <!-- 单位是:分钟 -->
    <session-timeout>5</session-timeout>
</session-config>
疑问:设置web.xml的会话配置,并且在代码中设置会话过期的时间,以哪个为准?
  • 就近的原则,以代码中的为准(代码会把配置文件的覆盖了)
方式三:立刻失效
  • session.invalidate()

    • 让会话立刻失效,一般用在注销或退出

案例

需求:用户登录的时候使用验证码进行验证
登录成功后将用户信息保存到会话域中,并且跳转到WelcomeServlet,然后在WeclcomeServlet中读取用户信息,显示欢迎信息。在WelcomeServlet上显示退出的链接,点退出,注销会话信息。

image
8.2 LoginServlet实现步骤:
1) 使用昨天的代码实现验证码的绘制
3) 用户登录的时候提交验证码的字符串
4) 比较表单提交的字符串是否与会话域中的字符串相等,如果相等则验证成功
5) 登录一次以后删除会话域中的验证码字符串
6) 登录成功以后保存用户的信息到会话域中,并且跳转到WelcomeServlet

8.3 WelcomeServlet的实现步骤:
1) 从会话域中取出用户信息并且显示
2) 判断用户是否正常登录,如果是非法用户则跳转到登录页面
3) 在页面上输出一个注销的连接,点注销跳转到LogoutServlet
8.4 LogoutServlet的实现步骤:
1) 让会话立刻过期
2) 显示您已经成功退出

Code

loginServlet:

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    //设置编码问题
    response.setContentType("text/html");
    response.setCharacterEncoding("utf-8");
    //获得打印流
    PrintWriter writer = response.getWriter();
    //获得会话对象
    HttpSession session = request.getSession();
    //获得会话域中的验证码的值
    String sessionVcode=(String) session.getAttribute("vcode");
    //删除验证码使得验证码只能使用一次
    session.removeAttribute("vcode");
    //获得表单提交的参数
    String vcode =request.getParameter("vcode");
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    //获得业务层对象
    UserService userService=new UserService();
    //通过业务层的方法查找这用户名是否存在对象
    User user = userService.getUser(username);
    writer.print("<script>");
    //先判断验证码是否正确
    if(vcode.equalsIgnoreCase(sessionVcode)){
        //判断找到的用户是否为空
        if(user!=null){
            System.out.println(user);
            //判断用户名和密码是否正确
            if(username.equals(user.getUsername())&&password.equals(user.getPassword())){
                //先把用户的信息存在会话域中
                session.setAttribute("user", user);
                //然后跳转到登陆成功的页面
                response.sendRedirect(request.getContextPath()+"/welcome");
            }else{
                //作出提示并跳转
                writer.print("alert('密码不正确');");
                writer.print("location.href='login.html'");
            }
            }else{
                //作出提示并跳转
                writer.print("alert('用户名密码不正确');");
                writer.print("location.href='login.html'");
            }
    }else{
        //作出提示并跳转
        writer.print("alert('验证码不正确');");
        writer.print("location.href='login.html'");
    }
    writer.print("</script>");
}

WelcomeServlet:

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //设置编码问题
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html");
    //获得打印流
    PrintWriter out = response.getWriter();
    //获得会话对象
    HttpSession session = request.getSession();
    //通过会话域获得User对象
    User user =(User) session.getAttribute("user");
    //判断是否非法访问,
    if(user==null){
        //帮他跳转到用户登陆
        response.sendRedirect(request.getContextPath()+"/login.html");
        return;
    }
    //界面的显示
    out.print("<h1>WelcomeServlet</h1><br/>");
    out.print("<h2>欢迎你!"+user.getUsername()+"!</h2><br/>");
    out.print("<a href='logout'>退出</a>");
    out.close();
}

logoutServlet:

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //设置编码的问题
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html");
    //获得打印流
    PrintWriter out = response.getWriter();
    //让用户的信息失效,注销
    request.getSession().invalidate();
    //界面显示
    out.print("<h1>LogoutServlet</h1><br/>");
    out.print("<a href='login.html'>返回登陆界面</a>");
    out.close();
}
other

PicCodeServlet:
动态验证码:

package com.Servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 验证码
 * 
 * @author NewBoy
 * 
 */
public class PicCodeServlet extends HttpServlet {

    private Random ran = new Random();

    // 1) 写一个方法随机获取颜色
    private Color getColor() {
        // 随机得到0~255之间整数
        int r = ran.nextInt(256);
        int g = ran.nextInt(256);
        int b = ran.nextInt(256);
        return new Color(r, g, b);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        int width = 90;
        int height =30;
        // 2) 创建缓存图片:指定宽width=90,高height=30
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 3) 获取画笔对象
        Graphics graphics = img.getGraphics();
        // 4) 设置画笔颜色
        graphics.setColor(Color.WHITE);
        //填充矩形区域
        graphics.fillRect(0, 0, width, height);
        // 5) 从字符数组中随机得到字符 

        //创建会话
        HttpSession session = request.getSession();
        StringBuilder sb=new StringBuilder();
        char[] arr = { 'A', 'B', 'C', 'D', 'N', 'E', 'W', 'b', 'o', 'y', '1', '2', '3', '4' };
        for (int i = 0; i < 4; i++) {
            //随机得到一个下标
            int index = ran.nextInt(arr.length);
            char c = arr[index];
            sb.append(c);
            //画字符
            // 6) 设置字体,大小为18,设置字的颜色随机
            graphics.setColor(getColor());
            //设置字体:大小,加粗,斜体
            graphics.setFont(new Font(Font.DIALOG, Font.BOLD + Font.ITALIC, 18));
            // 7) 将每个字符画到图片,位置:5+(i*20), 20
            graphics.drawString(String.valueOf(c),5+(i*20), 20);
        }
        //得到验证码,放到会话域中
        session.setAttribute("vcode",sb.toString());
        System.out.println(sb.toString());
        // 8) 画干扰线7条线,线的位置是随机的,x范围在width之中,y的范围在height之中。
        for (int i = 0; i < 7; i++) {
            int x1 = ran.nextInt(width);
            int y1 = ran.nextInt(height);
            int x2 = ran.nextInt(width);
            int y2 = ran.nextInt(height);
            //随机设置颜色
            graphics.setColor(getColor());
            graphics.drawLine(x1, y1, x2, y2);
        }
        // 9) 将缓存的图片输出到响应输出流中,参数:图片,格式,输出流
        ImageIO.write(img, "png", response.getOutputStream());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

login.html

<!DOCTYPE html>
<html>
<head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>会员登录</title>
        <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
        <script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
        <script src="js/bootstrap.min.js" type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet" href="css/style.css" type="text/css"/>

<style>
  body{
   margin-top:20px;
   margin:0 auto;
 }
 .carousel-inner .item img{
     width:100%;
     height:300px;
 }
 .container .row div{ 
     /* position:relative;
     float:left; */
 }

font {
    color: #666;
    font-size: 22px;
    font-weight: normal;
    padding-right:17px;
}
 </style>
</head>
<script type="text/javascript">
    $(function(){
        $("#vcode").click(function(){
            $(this).attr("src","vcode?t="+Math.random());
        });
    })
</script>
<body>

            <!--
                描述:菜单栏
            -->
            <div class="container-fluid">
                <div class="col-md-4">
                    <img src="img/logo2.png" />
                </div>
                <div class="col-md-5">
                    <img src="img/header.png" />
                </div>
                <div class="col-md-3" style="padding-top:20px">
                    <ol class="list-inline">
                        <li><a href="login.htm">登录</a></li>
                        <li><a href="register.htm">注册</a></li>
                        <li><a href="cart.htm">购物车</a></li>
                    </ol>
                </div>
            </div>
            <!--
                描述:导航条
            -->
            <div class="container-fluid">
                <nav class="navbar navbar-inverse">
                    <div class="container-fluid">
                        <!-- Brand and toggle get grouped for better mobile display -->
                        <div class="navbar-header">
                            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                                <span class="sr-only">Toggle navigation</span>
                                <span class="icon-bar"></span>
                                <span class="icon-bar"></span>
                                <span class="icon-bar"></span>
                            </button>
                            <a class="navbar-brand" href="#">首页</a>
                        </div>

                        <!-- Collect the nav links, forms, and other content for toggling -->
                        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                            <ul class="nav navbar-nav">
                                <li class="active"><a href="#">手机数码<span class="sr-only">(current)</span></a></li>
                                <li><a href="#">电脑办公</a></li>
                                <li><a href="#">电脑办公</a></li>
                                <li><a href="#">电脑办公</a></li>
                            </ul>
                            <form class="navbar-form navbar-right" role="search">
                                <div class="form-group">
                                    <input type="text" class="form-control" placeholder="Search">
                                </div>
                                <button type="submit" class="btn btn-default">Submit</button>
                            </form>

                        </div>
                        <!-- /.navbar-collapse -->
                    </div>
                    <!-- /.container-fluid -->
                </nav>
            </div>

<div class="container"  style="width:100%;height:460px;background:#FF2C4C url('img/loginbg.jpg') no-repeat;">
<div class="row"> 
    <div class="col-md-7">
        <!--<img src="./img/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">-->
    </div>

    <div class="col-md-5">
                <div style="width:440px;border:1px solid #E7E7E7;padding:20px 0 20px 30px;border-radius:5px;margin-top:60px;background:#fff;">
                <font>会员登录</font>USER LOGIN

                <div>&nbsp;</div>
<form class="form-horizontal" action="login" method="post">

 <div class="form-group">
    <label for="username" class="col-sm-2 control-label">用户名</label>
    <div class="col-sm-6">
      <input type="text" class="form-control" id="username" placeholder="请输入用户名" name="username">
    </div>
  </div>
   <div class="form-group">
    <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
    <div class="col-sm-6">
      <input type="password" class="form-control" id="inputPassword3" placeholder="请输入密码" name="password">
    </div>
  </div>
   <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
    <div class="col-sm-3">
      <input type="text" class="form-control" id="inputPassword3" placeholder="请输入验证码" name="vcode">
    </div>
    <div class="col-sm-3">
      <img src="vcode" id="vcode" title="看不清" style="cursor:pointer"/>
    </div>

  </div>
   <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <div class="checkbox">
        <label>
          <input type="checkbox"> 自动登录
        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <label>
          <input type="checkbox"> 记住用户名
        </label>
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
    <input type="submit"  width="100" value="登录" name="submit" border="0"
    style="background: url('./img/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);
    height:35px;width:100px;color:white;">
    </div>
  </div>
</form>
</div>          
    </div>
</div>
</div>  

    <div style="margin-top:50px;">
            <img src="./img/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" />
        </div>

        <div style="text-align: center;margin-top: 5px;">
            <ul class="list-inline">
                <li><a>关于我们</a></li>
                <li><a>联系我们</a></li>
                <li><a>招贤纳士</a></li>
                <li><a>法律声明</a></li>
                <li><a>友情链接</a></li>
                <li><a target="_blank">支付方式</a></li>
                <li><a target="_blank">配送方式</a></li>
                <li><a>服务声明</a></li>
                <li><a>广告声明</a></li>
            </ul>
        </div>
        <div style="text-align: center;margin-top: 5px;margin-bottom:20px;">
            Copyright &copy; 2005-2016 传智商城 版权所有
        </div>
</body></html>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值