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 <!-- Promise polyfill for IE11 -->
61 <script src=
"vendor/promise.js"></script>
63 <!-- ES2015/ES6 modules polyfill -->
64 <script nomodule
src=
"vendor/browser-es-module-loader/dist/browser-es-module-loader.js"></script>
66 <!-- actual script modules -->
67 <script type=
"module" crossorigin=
"anonymous">
68 // RFB holds the API to connect and communicate with a VNC server
69 import RFB from './core/rfb.js';
74 // When this function is called we have
75 // successfully connected to a server
76 function connectedToServer(e) {
77 status(
"Connected to " + desktopName);
80 // This function is called when we are disconnected
81 function disconnectedFromServer(e) {
83 status(
"Disconnected");
85 status(
"Something went wrong, connection is closed");
89 // When this function is called, the server requires
90 // credentials to authenticate
91 function credentialsAreRequired(e) {
92 const password = prompt(
"Password Required:");
93 rfb.sendCredentials({ password: password });
96 // When this function is called we have received
97 // a desktop name from the server
98 function updateDesktopName(e) {
99 desktopName = e.detail.name;
102 // Since most operating systems will catch Ctrl+Alt+Del
103 // before they get a chance to be intercepted by the browser,
104 // we provide a way to emulate this key sequence.
105 function sendCtrlAltDel() {
106 rfb.sendCtrlAltDel();
110 // Show a status text in the top bar
111 function status(text) {
112 document.getElementById('status').textContent = text;
115 // This function extracts the value of one variable from the
116 // query string. If the variable isn't defined in the URL
117 // it returns the default value instead.
118 function readQueryVariable(name, defaultValue) {
119 // A URL with a query parameter can look like this:
120 // https://www.example.com?myqueryparam=myvalue
122 // Note that we use location.href instead of location.search
123 // because Firefox <
53 has a bug w.r.t location.search
124 const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
125 match = document.location.href.match(re);
126 if (typeof defaultValue === 'undefined') { defaultValue = null; }
129 // We have to decode the URL since want the cleartext value
130 return decodeURIComponent(match[
1]);
136 document.getElementById('sendCtrlAltDelButton')
137 .onclick = sendCtrlAltDel;
139 // Read parameters specified in the URL query string
140 // By default, use the host and port of server that served this file
141 const host = readQueryVariable('host', window.location.hostname);
142 let port = readQueryVariable('port', window.location.port);
143 const password = readQueryVariable('password');
144 const path = readQueryVariable('path', 'websockify');
147 // | | | Connect | | |
150 status(
"Connecting");
152 // Build the websocket URL used to connect
154 if (window.location.protocol ===
"https:") {
165 // Creating a new RFB object will start a new connection
166 rfb = new RFB(document.getElementById('screen'), url,
167 { credentials: { password: password } });
169 // Add listeners to important events from the RFB module
170 rfb.addEventListener(
"connect", connectedToServer);
171 rfb.addEventListener(
"disconnect", disconnectedFromServer);
172 rfb.addEventListener(
"credentialsrequired", credentialsAreRequired);
173 rfb.addEventListener(
"desktopname", updateDesktopName);
175 // Set parameters that can be changed on an active connection
176 rfb.viewOnly = readQueryVariable('view_only', false);
177 rfb.scaleViewport = readQueryVariable('scale', false);
183 <div id=
"status">Loading
</div>
184 <div id=
"sendCtrlAltDelButton">Send CtrlAltDel
</div>
187 <!-- This is where the remote screen will appear -->