内容纲要

FreeRDP-WebConnect 支持 html5 websocket 连接,可连接 hyper-v 的 vm,需要传一个 vmid。重点配置 rdpoverride 节,覆盖相关参数后,只提供一个 vmid 即可连接。

wsgate.ini

[global]
debug=false
redirect=false
port=8082
bindaddr=0.0.0.0
[http]
documentroot=D:\FreeRDP-WebConnect\WebRoot\
[ssl]
port=4430
bindaddr=0.0.0.0
certfile=D:\FreeRDP-WebConnect\etc\server.cer
[rdpoverride]
nofullwindowdrag=true
host = localhost
port = 2179
user = Administrator
pass = Aa123456
performance = 0
[openstack]
keystoneversion=v3
authurl=http://keystone:5000/v3/
username=admin
password=
projectname=admin
projectdomainname=Default
userdomainname=Default
[hyperv]
hostusername=Administrator
hostpassword=

index.html

<!DOCTYPE html>
<html>

<head>
    <link href='css/quicksand.css' rel='stylesheet' type='text/css'>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>FreeRDP WebConnect: offline</title>
    <meta name="robots" content="nofollow" />
    <meta name="description" content="A HTML5 based RDP client">
    <meta name="viewport" content="width=device-width height=device-height user-scalable=no">
    <meta name="cursor-event-mode" content="native">
    <meta name="touch-event-mode" content="pure-with-mouse-conversion">
    <link rel="stylesheet" href="css/style%JSDEBUG%.css">
    <link rel="stylesheet" href="css/vkb%JSDEBUG%.css">
    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <script src="js/modernizr%JSDEBUG%.js"></script>
    <script src="js/mootools%JSDEBUG%.js"></script>
    <script src="js/simpletabs%JSDEBUG%.js"></script>
    <script src="js/wsgate%JSDEBUG%.js"></script>
    <script src="js/vkb%JSDEBUG%.js"></script>
    <!--<script language="javascript" type="text/javascript" src="js/rdpevents%JSDEBUG%.js"></script>-->
    <script language="javascript" type="text/javascript">
        var wsBase = "%WSURI%";
        var RIMtablet = navigator.appVersion && (-1 != navigator.appVersion.indexOf('RIM Tablet'));
        var mhx = 100;
        var mhy = 100;
        var dragX = 0;
        var dragY = 0;
        var inDrag = false;
        var rdp = null;
        var vkbd = null;
        var embedded = false;

        var externalConnection = false;

        function initBody() {
            //apply old settings
            settingsApply();
            initPopUpDeck();
        }

        //pop up message procedure
        var popUpDeck = null;
        var popUpElements = [];

        function initPopUpDeck() {
            popUpDeck = document.createElement('div');
            document.body.appendChild(popUpDeck);

            popUpDeck.set('class', 'popupwrapper');
        }

        function cleanPopUpDeck() {
            for (var i = 0; i < popUpElements.length; i++) {
                popUpElements[i].removeEvents();
                popUpElements[i].destroy();
            }
        }

        function popUpMessage(type, msg, timeout, callback, center) {
            var newMessage = document.createElement('div');
            popUpDeck.appendChild(newMessage);

            newMessage.set('class', 'popupmessage');
            newMessage.set('text', msg);
            newMessage.addEvent('mousedown',
                function () {
                    if (callback)
                        callback();
                    newMessage.destroy();
                    newMessage = null;
                });

            var color = {
                r: 255,
                g: 255,
                b: 255
            };

            if (type == 'error') {
                color.r = 247;
                color.g = 203;
                color.b = 30;
            } else
            if (type == 'message') {
                color.r = 107;
                color.g = 180;
                color.b = 229;
            } else
            if (type == 'critical') {
                color.r = 255;
                color.g = 0;
                color.b = 0;
            }

            if (center) {
                newMessage.setStyle('position', 'absolute');
                newMessage.setStyle('top', document.body.offsetHeight / 2);
                newMessage.setStyle('z-index', '1235');
            }
            newMessage.setStyle('background-color', 'rgba(' + color.r +
                ',' + color.g +
                ',' + color.b +
                ', 0.8)');

            if (timeout) {
                window.setTimeout(
                    function () {
                        if (newMessage) {
                            if (callback)
                                callback();
                            newMessage.destroy();
                        }
                    },
                    timeout * 1000);
            }

            popUpElements.push(newMessage);

            return newMessage;
        }

        function noInstancePopUp() {
            popUpMessage('critical', "This instance seems to be not working. Try to enter the console again.", 0,
                noInstancePopUp, true);
        }

        function RDPStart(uri, title) {
            if (uri === undefined) {
                uri = wsBase;
            }
            if (title === undefined) {
                //title = "FreeRDP WebConnect: connected to " + $('rdphost').value.trim();
            }
            if (!embedded) {
                $('dvLoading').setStyles({
                    'visibility': 'visible'
                });
            }
            rdp = new wsgate.RDP(uri, $('screen'), !RIMtablet, RIMtablet, vkbd);

            rdp.addEvent('alert', function (msg) {
                popUpMessage('error', msg, 5);
            });
            rdp.addEvent('connected', function () {
                cleanPopUpDeck();
                document.title = title;
                button = $("rdpconnect");
                button.removeEvents();
                window.removeEvent('resize', OnDesktopSize);
                button.value = 'Disconnect';
                button.addEvent('click', rdp.Disconnect.bind(rdp));
                window.addEvent("beforeunload", rdp.Disconnect.bind(rdp));
            });
            rdp.addEvent('disconnected', function () {
                showDialog(true);
                if (embedded) {
                    $('maindialog').addClass('invisible');
                    noInstancePopUp()
                }
                button = $("rdpconnect");
                button.removeEvents();
                button.value = 'Connect';
                button.addEvent('click', function () {
                    RDPStart();
                });
                OnDesktopSize();
                window.addEvent('resize', OnDesktopSize);
            });
            rdp.addEvent('mouserelease', ResetRdpMouseFlags);
            rdp.addEvent('touch2', function () {
                ShowMouseHelper($('mousehelper').hasClass('invisible'));
            });
            rdp.addEvent('touch3', function () {
                vkbd.toggle();
            });
            rdp.addEvent('touch4', function () {
                if (confirm('Are you sure you want to disconnect?')) {
                    rdp.Disconnect();
                }
            });
            showDialog(false);
            rdp.Run();
        }

        function SetRdpMouseFlags() {
            var mf = {
                'r': $('rclick').checked,
                'm': $('mclick').checked,
                'a': $('aclick').checked,
                's': $('sclick').checked,
                'c': $('cclick').checked,
            };
            rdp.SetArtificialMouseFlags(mf);
        }

        function ResetRdpMouseFlags() {
            $('rclick').checked = false;
            $('mclick').checked = false;
            $('aclick').checked = false;
            $('sclick').checked = false;
            $('cclick').checked = false;
            rdp.SetArtificialMouseFlags(null);
        }

        function ShowMouseHelper(show) {
            var mh = $('mousehelper');
            inDrag = false;
            if (show) {
                mh.setStyles({
                    'position': 'absolute',
                    'top': mhy,
                    'left': mhx,
                    'z-index': 999
                });
                mh.addEvent('mousedown', DragStart);
                $('rclick').addEvent('change', SetRdpMouseFlags);
                $('mclick').addEvent('change', SetRdpMouseFlags);
                $('aclick').addEvent('change', SetRdpMouseFlags);
                $('sclick').addEvent('change', SetRdpMouseFlags);
                $('cclick').addEvent('change', SetRdpMouseFlags);
                mh.removeClass('invisible');
            } else {
                mh.removeEvents();
                mh.addClass('invisible');
                $('rclick').removeEvents();
                $('mclick').removeEvents();
                $('aclick').removeEvents();
                $('sclick').removeEvents();
                $('cclick').removeEvents();
            }
        }

        function OnDesktopSize() {
            ResizeCanvas($('dtsize').value);
            DrawLogo();
        }

        function DragStart(evt) {
            var mh = $('mousehelper');
            if (!mh.hasClass('invisible')) {
                inDrag = true;
                dragX = evt.page.x;
                dragY = evt.page.y;
                window.addEvent('mouseup', DragEnd);
                window.addEvent('touchmove', DragMove);
            }
        }

        function DragEnd(evt) {
            inDrag = false;
            var mh = $('mousehelper');
            window.removeEvent('touchmove', DragMove);
            window.removeEvent('mouseup', DragEnd);
        }

        function DragMove(evt) {
            if (inDrag) {
                var dx = evt.page.x - dragX;
                var dy = evt.page.y - dragY;
                dragX = evt.page.x;
                dragY = evt.page.y;
                var mh = $('mousehelper');
                if (!mh.hasClass('invisible')) {
                    mhx += dx;
                    mhy += dy;
                    mh.setStyles({
                        'top': mhy,
                        'left': mhx
                    });
                }
            }
        }

        function DrawLogo() {
            var logo = new Element('img', {
                'src': 'empty_on_purpose'
            });
            logo.addEvent('load', function () {
                var scaleWCoeficient = 0.5;
                var scaleHCoeficient = 0.5;
                var iw = this.width * scaleWCoeficient;
                var ih = this.height * scaleHCoeficient;
                var scale = ($('screen').height - 20) / ih;
                $('screen').getContext('2d').drawImage(this, 10, 10, Math.round(iw * scale), Math.round(ih *
                    scale));
            }.bind(logo));
        }

        function ResizeCanvas(sz) {
            var w, h;
            if (sz == 'auto') {
                w = window.getCoordinates().width;
                h = window.getCoordinates().height;
                if (RIMtablet) {
                    // Toplevel bar not removable
                    h -= 31;
                }
                if (w % 2) {
                    w -= 1;
                }
            } else {
                var sza = sz.split('x');
                var w = sza[0];
                var h = sza[1];
            }
            $('screen').width = w - 50;
            $('screen').height = h - 50;
            $('screen').style["margin"] = "0 auto";
        }

        var sendDisconnect = function () {
            if (confirm('Are you sure you want to disconnect ?')) {
                $('extracommands').setStyles({
                    'visibility': 'hidden'
                });
                rdp.Disconnect();
            }
        }

        var altTabOn = false;

        function altTabEvent() {
            if (altTabOn) {
                altTabOn = false;
                rdp.SendKey(2); //alt+tab release
                $('alttab').removeClass('extracommandshold');
            } else {
                altTabOn = true;
                rdp.SendKey(1); //alt+tab
                $('alttab').addClass('extracommandshold');
            }
        }

        function showDialog(show) {
            if (show) {
                ShowMouseHelper(false);
                var dlg = $('maindialog');
                var x = Math.round((window.getCoordinates().width - dlg.getCoordinates().width) / 2) + 'px';
                var y = Math.round((window.getCoordinates().height - dlg.getCoordinates().height) / 2) + 'px';
                $('extracommands').setStyles({
                    'visibility': 'hidden'
                });
                $('dvLoading').setStyles({
                    'visibility': 'hidden'
                });
                DrawLogo();
                dlg.setStyles({
                    'position': 'absolute',
                    'top': y,
                    'left': x,
                    'z-index': 999
                }).removeClass('invisible');
            } else {
                $('maindialog').addClass('invisible');
                $('extracommands').setStyles({
                    'visibility': 'visible'
                });
                $('ctrlaltdelete').addEvent('click', function () {
                    rdp.SendKey(0);
                });
                $('alttab').addEvent('click', altTabEvent);
                $('disconnect').addEvent('click', sendDisconnect);
            }
        }

        var RDPCookieKey = "RDPinfoJSON";
        //sets a cookie with the settings inserted in the form
        function settingsSet() {
            var infoJSON = settingsGetJSON();
            //remove password
            infoJSON.pass = "";
            document.cookie = RDPCookieKey + "=" + JSON.stringify(infoJSON) +
                "; expires=Fri, 31 Dec 2030 23:59:59 GMT;";
        }
        //change the form fields with respect with the cookie
        function settingsApply() {
            var cookie = document.cookie;
            if (cookie) {
                var cookieValues = cookie.split(';');
                var i = 0;
                //get the cookie for infoJSON
                while (cookieValues[i].indexOf(RDPCookieKey) == -1) {
                    i++;
                }
                //get the value of the cookie then parse it to a JSON
                try {
                    var infoJSON = JSON.parse(cookieValues[i].split('=')[1]);
                    //if we found a JSON we apply the values to the form fields
                    if (infoJSON) {
                        $('rdphost').set('value', infoJSON.host);
                        $('rdpport').set('value', infoJSON.port);
                        $('rdppcb').set('value', infoJSON.pcb);
                        $('rdpuser').set('value', infoJSON.user);
                        $('nowallp').set('checked', infoJSON.nowallp != 0);
                        $('nowdrag').set('checked', infoJSON.nowdrag != 0);
                        $('nomani').set('checked', infoJSON.nomani != 0);
                        $('notheme').set('checked', infoJSON.notheme != 0);
                        $('nonla').set('checked', infoJSON.nonla != 0);
                        $('notls').set('checked', infoJSON.notls != 0);
                    }
                } catch (e) {
                    console.log("Bad JSON format");
                    console.log(e.message);
                }
            }
        }
        //gets a JSON with the settings inserted in the form
        function settingsGetJSON() {
            return {
                "host": 'localhost' //$('rdphost').value.trim()
                    ,
                "port": parseInt($('rdpport').value.trim()),
                "pcb": $('vmid').value.trim() //$('rdppcb').value.trim()
                    ,
                "user": 'user' //$('rdpuser').value.trim()
                    ,
                "pass": 'pass' //$('rdppass').value
                    ,
                "perf": parseInt($('perf').value.trim()),
                "fntlm": parseInt($('fntlm').value.trim()),
                "nowallp": parseInt($('nowallp').checked ? '1' : '0'),
                "nowdrag": parseInt($('nowdrag').checked ? '1' : '0'),
                "nomani": parseInt($('nomani').checked ? '1' : '0'),
                "notheme": parseInt($('notheme').checked ? '1' : '0'),
                "nonla": parseInt($('nonla').checked ? '1' : '0'),
                "notls": parseInt($('notls').checked ? '1' : '0'),
                "dtsize": $('screen').width + 'x' + $('screen').height
            };
        }

        window.addEventListener("beforeunload", function () {
            if ($('maindialog').hasClass('invisible')) {
                var ans = confirm("Are you sure you want to disconnect?");
                if (ans) {
                    rdp.Disconnect();
                }
            }
        }, false);

        window.addEvent('domready', function () {

            var querystring = window.location.href.slice(window.location.href.indexOf('?'))

            $('dtsize').addEvent('change', OnDesktopSize);
            var tabs = new SimpleTabs('rdpdialog', {
                selector: 'h4'
            });
            OnDesktopSize();
            if (RIMtablet) {
                // Set default performance flags to modem
                $('perf').value = '2';
            }
            window.addEvent('resize', OnDesktopSize);
            // Special handling of webkit nightly builds
            var webkitOK = false;
            var wkVA = RegExp("( AppleWebKit/)([^ ]+)").exec(navigator.userAgent);
            if (wkVA && (wkVA.length > 2)) {
                if (wkVA[2].indexOf('+') != -1) {
                    webkitOK = true;
                }
            }
            var wsOK = RIMtablet || webkitOK ||
                (Browser.firefox && (Browser.version >= 11.0)) ||
                (Browser.chrome && (Browser.version >= 17)) ||
                (Browser.safari && (Browser.version >= 6)) ||
                (Browser.ie && (Browser.version >= 10.0));
            if (externalConnection == true) {
                RDPStart();
                vkbd = new wsgate.vkbd({
                    version: false,
                    sizeswitch: false,
                    numpadtoggle: false
                });
            }
            if (wsOK) {
                if (querystring.length > 2) {
                    showDialog(false);
                    if (querystring.indexOf('token=') >= 0) {
                        $('disconnect').setStyles({
                            'visibility': 'hidden'
                        });
                        embedded = true;
                    }
                    var urlParams;
                    (window.onpopstate = function () {
                        var match,
                            pl = /\+/g, // Regex for replacing addition symbol with a space
                            search = /([^&=]+)=?([^&]*)/g,
                            decode = function (s) {
                                return decodeURIComponent(s.replace(pl, " "));
                            },
                            query = window.location.search.substring(1);

                        urlParams = {};
                        while (match = search.exec(query))
                            urlParams[decode(match[1])] = decode(match[2]);
                    })();
                    RDPStart(wsBase + querystring, urlParams["title"]);
                } else {
                    $('rdpconnect').addEvent('click', function () {
                        RDPStart();
                    });
                    $('btnConnect').addEvent('click', function () {
                        RDPStart();
                    });
                    showDialog(true);
                }
                vkbd = new wsgate.vkbd({
                    version: false,
                    sizeswitch: false,
                    numpadtoggle: false
                });
            } else {
                alert('Sorry!\nYour Browser (' + Browser.name + ' ' + Browser.version +
                    ') does not yet\nprovide the required HTML5 features ' +
                    'for this application.\n');
            }
        });
    </script>
</head>

<body id="wrapper" onload="initBody()">
    <div id="extracommands"
        style="height:28px; background-color:#f1f1f1; padding-left:25px; cursor:default; visibility:hidden;">
        Send keys:
        <ul>

            <li id="ctrlaltdelete">
                Ctrl+Alt+Delete
            </li>
            <li id="alttab">
                Alt+Tab
            </li>
            <li id="keyboardlanguage">
                Multilanguage keyboard
            </li>
        </ul>
        <button id="disconnect" type="button" style="float:right; margin-right:40px; margin-top:2px">Disconnect</button>
    </div>
    <div id="IMEhelper"
        style="z-index:1111;visibility:hidden;height:auto;width:auto;display:inline;position:absolute;background-color:#ffffff;">
    </div>
    <canvas id="screen">
        <p class="error">Sorry, It looks as though your browser does not support the canvas tag.</p>
    </canvas>
    <div id="dvLoading" style="position:fixed; left:45%; top:45%; visibility:hidden;"><img src="images/loading.gif">
    </div>
    <noscript>
        <p class="error">Please enable JavaScript.</p>
    </noscript>
    <table width="400px" id="maindialog" class="invisible">
        <tr>
            <td>
                <div style="margin-left:auto; margin-right:auto; width:60%; position:relative;">
                    <a href="http://www.cloudbase.it">
                        <img src='images/CBSL_web_logo3.png' style="margin-left:auto; margin-right:auto;">
                    </a></div></img>
            </td>
        </tr>
        <tr>
            <td>
                <div id="rdpdialog" class="dialog">
                    <h4 title="Main connection settings">General</h4>

                    <div>
                        <div>
                            <labe for="vmid">VMID:</labe><input type="text" id="vmid" /> <br>
                            <input type="button" id="btnConnect" value="连接" />
                        </div>
                        <form
                            onkeypress="if (event.keyCode == 13) { document.getElementById('rdpconnect').focus();document.getElementById('rdpconnect').click(); return event.preventDefault();}">
                            <fieldset>
                                <legend>Session parameters</legend>
                                <table>
                                    <!--<tr>
                                            <td class="key"><label for="host">Hostname:</label></td>
                                            <td><input id="rdphost" type="text" name="host" value="%COOKIE_LASTHOST%" %DISABLED_HOST%/></td>
                                        </tr>
                                        <tr>
                                            <td class="key"><label for="user">User:</label></td>
                                            <td><input id="rdpuser" type="text" name="user" value="%COOKIE_LASTUSER%" %DISABLED_USER% /></td>
                                        </tr>
                                        <tr>
                                            <td class="key"><label for="pass">Password:</label></td>
                                            <td><input id="rdppass" type="password" name="pass" value="%COOKIE_LASTPASS%" autocomplete="off" %DISABLED_PASS% /></td>
                                        </tr>-->
                                    <tr>
                                        <td class="key"><label for="dtsize">Desktop size:</label></td>
                                        <td>
                                            <select id="dtsize" name="dtsize">
                                                <option>640x480</option>
                                                <option>800x600</option>
                                                <option>1024x768</option>
                                                <option>1280x960</option>
                                                <option>1280x1024</option>
                                                <option value="auto" selected>Available Area</option>
                                            </select>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="buttons" colspan="2"><input id="rdpconnect" type="button"
                                                value="Connect" /></td>
                                    </tr>
                                </table>
                            </fieldset>
                        </form>
                    </div>
                    <h4 title="Advanced session parameters">Advanced</h4>
                    <div>
                        <form onsubmit="event.preventDefault(); return false;">
                            <fieldset>
                                <legend>Advanced session parameters</legend>
                                <table>
                                    <tr>
                                        <td class="key"><label for="port">Port:</label></td>
                                        <td><input id="rdpport" name="port" type="text" size="6" maxlen="5"
                                                value="%DEFAULT_PORT%" %DISABLED_PORT% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="pcb">PCB (vmID):</label></td>
                                        <td><input id="rdppcb" type="text" name="pcb" value="%COOKIE_LASTPCB%"
                                                %DISABLED_PCB% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="perf">Performance:</label></td>
                                        <td>
                                            <select id="perf" name="perf" %DISABLED_PERF%>
                                                <option value="0" %SELECTED_PERF0%>LAN</option>
                                                <option value="1" %SELECTED_PERF1%>Broadband</option>
                                                <option value="2" %SELECTED_PERF2%>Modem</option>
                                            </select>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="nowallp">Disable wallpaper:</label></td>
                                        <td><input id="nowallp" name="nowallp" type="checkbox" %CHECKED_NOWALLP% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="nowdrag">Disable full window drag:</label></td>
                                        <td><input id="nowdrag" name="nowdrag" type="checkbox" %CHECKED_NOWDRAG% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="nomani">Disable menu animation:</label></td>
                                        <td><input id="nomani" name="nomani" type="checkbox" %CHECKED_NOMANI% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="notheme">Disable theming:</label></td>
                                        <td><input id="notheme" name="notheme" type="checkbox" %CHECKED_NOTHEME% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="nonla">Disable network level authentication:</label>
                                        </td>
                                        <td><input id="nonla" name="nonla" type="checkbox" %CHECKED_NONLA% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="notls">Disable TLS:</label></td>
                                        <td><input id="notls" name="notls" type="checkbox" %CHECKED_NOTLS% /></td>
                                    </tr>
                                    <tr>
                                        <td class="key"><label for="fntlm">Force NTLM auth:</label></td>
                                        <td>
                                            <select id="fntlm" name="fntlm" %DISABLED_FNTLM%>
                                                <option value="0" %SELECTED_FNTLM0%>disabled</option>
                                                <option value="1" %SELECTED_FNTLM1%>NTLM v1</option>
                                                <option value="2" %SELECTED_FNTLM2%>NTLM v2</option>
                                            </select>
                                        </td>
                                    </tr>
                                </table>
                            </fieldset>
                        </form>
                        <br />
                    </div>
                    <h4 title="Show version info">About</h4>
                    <div class="about">
                        <h2>FreeRDP WebConnect</h2>
                        Version %VERSION%
                    </div>
                </div>
            </td>
        </tr>
    </table>
    <table width="240px" id="mousehelper" class="invisible">
        <tr>
            <td>
                <div id="mousedialog" class="dialog">
                    <form>
                        <fieldset>
                            <legend>Click properties</legend>
                            <table>
                                <tr>
                                    <td class="key"><label class="big" for="rclick">Right</label></td>
                                    <td><input id="rclick" name="rclick" type="checkbox" /></td>
                                </tr>
                                <tr>
                                    <td class="key"><label class="big" for="mclick">Middle</label></td>
                                    <td><input id="mclick" name="mclick" type="checkbox" /></td>
                                </tr>
                                <tr>
                                    <td class="key"><label class="big" for="aclick">Alt</label></td>
                                    <td><input id="aclick" name="aclick" type="checkbox" /></td>
                                </tr>
                                <tr>
                                    <td class="key"><label class="big" for="sclick">Shift</label></td>
                                    <td><input id="sclick" name="sclick" type="checkbox" /></td>
                                </tr>
                                <tr>
                                    <td class="key"><label class="big" for="cclick">Control</label></td>
                                    <td><input id="cclick" name="cclick" type="checkbox" /></td>
                                </tr>
                            </table>
                        </fieldset>
                    </form>
                </div>
            </td>
        </tr>
    </table>
</body>

</html>

参考

发表评论

电子邮件地址不会被公开。 必填项已用*标注