6 noVNC example: lightweight example using minimal UI and features
8 This is a self-contained file which doesn't import WebUtil or external CSS.
10 Copyright (C) 2019 The noVNC Authors
11 noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
12 This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
14 Connect parameters are provided in query string:
15 http://example.com/?host=HOST&port=PORT&scale=true
19 <meta charset=
"utf-8">
25 background-color: dimgrey;
28 flex-direction: column;
35 background-color: #
6e84a3;
37 font: bold
12px Helvetica;
38 padding:
6px
5px
4px
5px;
39 border-bottom:
1px outset;
44 #sendCtrlAltDelButton {
49 padding:
5px
5px
4px
5px;
54 flex:
1; /* fill remaining space */
60 <script type=
"module" crossorigin=
"anonymous">
61 // RFB holds the API to connect and communicate with a VNC server
62 import RFB from './core/rfb.js';
67 // When this function is called we have
68 // successfully connected to a server
69 function connectedToServer(e) {
70 status(
"Connected to " + desktopName);
73 // This function is called when we are disconnected
74 function disconnectedFromServer(e) {
76 status(
"Disconnected");
78 status(
"Something went wrong, connection is closed");
82 // When this function is called, the server requires
83 // credentials to authenticate
84 function credentialsAreRequired(e) {
85 const password = prompt(
"Password Required:");
86 rfb.sendCredentials({ password: password });
89 // When this function is called we have received
90 // a desktop name from the server
91 function updateDesktopName(e) {
92 desktopName = e.detail.name;
95 // Since most operating systems will catch Ctrl+Alt+Del
96 // before they get a chance to be intercepted by the browser,
97 // we provide a way to emulate this key sequence.
98 function sendCtrlAltDel() {
103 // Show a status text in the top bar
104 function status(text) {
105 document.getElementById('status').textContent = text;
108 // This function extracts the value of one variable from the
109 // query string. If the variable isn't defined in the URL
110 // it returns the default value instead.
111 function readQueryVariable(name, defaultValue) {
112 // A URL with a query parameter can look like this:
113 // https://www.example.com?myqueryparam=myvalue
115 // Note that we use location.href instead of location.search
116 // because Firefox <
53 has a bug w.r.t location.search
117 const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
118 match = document.location.href.match(re);
121 // We have to decode the URL since want the cleartext value
122 return decodeURIComponent(match[
1]);
128 document.getElementById('sendCtrlAltDelButton')
129 .onclick = sendCtrlAltDel;
131 // Read parameters specified in the URL query string
132 // By default, use the host and port of server that served this file
133 const host = readQueryVariable('host', window.location.hostname);
134 let port = readQueryVariable('port', window.location.port);
135 const password = readQueryVariable('password');
136 const path = readQueryVariable('path', 'websockify');
139 // | | | Connect | | |
142 status(
"Connecting");
144 // Build the websocket URL used to connect
146 if (window.location.protocol ===
"https:") {
157 // Creating a new RFB object will start a new connection
158 rfb = new RFB(document.getElementById('screen'), url,
159 { credentials: { password: password } });
161 // Add listeners to important events from the RFB module
162 rfb.addEventListener(
"connect", connectedToServer);
163 rfb.addEventListener(
"disconnect", disconnectedFromServer);
164 rfb.addEventListener(
"credentialsrequired", credentialsAreRequired);
165 rfb.addEventListener(
"desktopname", updateDesktopName);
167 // Set parameters that can be changed on an active connection
168 rfb.viewOnly = readQueryVariable('view_only', false);
169 rfb.scaleViewport = readQueryVariable('scale', false);
175 <div id=
"status">Loading
</div>
176 <div id=
"sendCtrlAltDelButton">Send CtrlAltDel
</div>
179 <!-- This is where the remote screen will appear -->