noVNC可以给linux系统提供基于VNC虚拟桌面的WEB服务,这使得openstack使用noVNC对外提供虚拟机的WEB版虚拟桌面。
不过用这个noVNC也有一些问题,在使用HTML2canvas截图或者使用一些需要外部操控的操作就出问题。
问题重现GIF如下:
经查,HTML2canvas这个js控件的工作原理是读取HTML元素,但是noVNC或openstack提供的noVNC窗口url都是与现在用的系统不同域(简单来说这些服务就是运行在不同的机子上),这一步因为headers不支持跨域的问题失败了——下载的截图noVNC画面部分为空白,键入F12查看控制台,显示Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
网上很多解决方案,无一不是在服务端修改配置、修改headers、修改HTML2canvas参数使被跨域的服务支持跨域,但是画面截图这个功能,发起者是外部系统,跨的域是noVNC或openstack的ip和端口,没有支持跨域的配置,又不能随意修改里面的代码,修改HTML2canvas参数也无效。
这时就有一个想法:既然noVNC的窗口本质上就是一堆HTML代码,是否可以将代码直接贴在本系统上?
noVNC窗口代码
<!DOCTYPE html> <html> <head> <!-- noVNC example: lightweight example using minimal UI and features Copyright (C) 2012 Joel Martin Copyright (C) 2017 Samuel Mannehed for Cendio AB noVNC is licensed under the MPL 2.0 (see LICENSE.txt) This file is licensed under the 2-Clause BSD license (see LICENSE.txt). Connect parameters are provided in query string: http://example.com/?host=HOST&port=PORT&encrypt=1 or the fragment: http://example.com/#host=HOST&port=PORT&encrypt=1 --> <title>noVNC</title> <meta charset="utf-8"> <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame Remove this if you use the .htaccess --> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- Icons (see Makefile for what the sizes are for) --> <link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png"> <link rel="icon" sizes="24x24" type="image/png" href="app/images/icons/novnc-24x24.png"> <link rel="icon" sizes="32x32" type="image/png" href="app/images/icons/novnc-32x32.png"> <link rel="icon" sizes="48x48" type="image/png" href="app/images/icons/novnc-48x48.png"> <link rel="icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png"> <link rel="icon" sizes="64x64" type="image/png" href="app/images/icons/novnc-64x64.png"> <link rel="icon" sizes="72x72" type="image/png" href="app/images/icons/novnc-72x72.png"> <link rel="icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png"> <link rel="icon" sizes="96x96" type="image/png" href="app/images/icons/novnc-96x96.png"> <link rel="icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png"> <link rel="icon" sizes="144x144" type="image/png" href="app/images/icons/novnc-144x144.png"> <link rel="icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png"> <link rel="icon" sizes="192x192" type="image/png" href="app/images/icons/novnc-192x192.png"> <!-- Firefox currently mishandles SVG, see #1419039 <link rel="icon" sizes="any" type="image/svg+xml" href="app/images/icons/novnc-icon.svg"> --> <!-- Repeated last so that legacy handling will pick this --> <link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png"> <!-- Apple iOS Safari settings --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <!-- Home Screen Icons (favourites and bookmarks use the normal icons) --> <link rel="apple-touch-icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png"> <link rel="apple-touch-icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png"> <link rel="apple-touch-icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png"> <link rel="apple-touch-icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png"> <!-- Stylesheets --> <link rel="stylesheet" href="app/styles/lite.css"> <!-- <script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script> --> <!-- promise polyfills promises for IE11 --> <script src="vendor/promise.js"></script> <!-- ES2015/ES6 modules polyfill --> <script type="module"> window._noVNC_has_module_support = true; </script> <script> window.addEventListener("load", function() { if (window._noVNC_has_module_support) return; var loader