Guacamole源码安装

Guacamole分为两部分:guacamole-server,提供Guacamole代理和相关库;以及guacamole-client,提供通过servlet容器(通常是Apache Tomcat)运行服务的客户端。

guacamole-client可以是二进制形式,但guacamole-server必须从源代码构建。不要怕:源代码方式构建Guacamole的组件并不像听起来那么难,而且构建过程是自动化的。你只需要确保提前安装了必要的工具。有了必要的依赖关系,制作Guacamole只需几分钟。

构建guacamole-server

guacamole-server包含Guacamole连接远程桌面所需的所有原生的服务端组件。它提供了一个通用的C库libguac,所有其他原生组件都依赖它,并为每个受支持的协议提供了单独的库,以及Guacamole的核心guacd

guacd是在Guacamole服务器上运行的代理守护进程,它接受用户通过Guacamole Web应用程序进行的隧道连接,然后代表用户连接到远程桌面。构建guacd会创建一个名为guacd的可执行文件,可以手动运行,或者在计算机启动时自动运行。

构建guacamole-server,需要一个C编译器(如gcc)和guacamole-server的依赖库。有些依赖项是必须的,而有些是可选的。存在可选依赖项则启用了附加功能。

❗重点:
许多Linux发行版将库包分为二进制包和“开发”包;你需要安装开发包。它们通常以“-dev”或“-devel”后缀结尾。

必需的依赖项

构建guacamole-server,需要Cairolibjpeg(或libjpeg-turbo)、libpng以及libuuid(或OSSP UUID库)。任何情况下这些库都是严格需要的,没有则无法构建Guacamole。

  • Cairo

    libguac使用Cairo进行图形渲染。如果不安装Cairo,Guacamole就不能运转。

    发行版 库名
    Debian / Ubuntu package libcairo2-dev
    Fedora / CentOS / RHEL package cairo-devel
  • libjpeg-turbo

    libguac使用libjpeg-turbo来提供JPEG支持。如果没有该库,Guacamole将无法构建。

    发行版 库名
    Debian package libjpeg62-turbo-dev
    Ubuntu package libjpeg-turbo8-dev
    Fedora / CentOS / RHEL package libjpeg-turbo-devel

    如果libjpeg-turbo在你的平台不可用,且你不想从源码构建它,也可以使用libjpeg ,但没有libjpeg-turbo那么快。

    发行版 库名
    Debian / Ubuntu package libjpeg62-dev
    Fedora / CentOS / RHEL package libjpeg-devel
  • libpng

    libpnglibguac用于PNG图像写入,这是Guacamole协议使用的核心图像类型。没有libpng,Guacamole无法运转。

    发行版 库名
    Debian / Ubuntu package libpng12-dev
    Fedora / CentOS / RHEL package libpng-devel
  • libtool

    libtool在构建过程中用于创建Guacamole所需的编译库。

    发行版 库名
    Debian / Ubuntu package libtool-bin
    Fedora / CentOS / RHEL package libtool
  • libuuid(util-linux 的一部分)

    libuuidlibguac用于为每个Guacamole用户和连接分配唯一的内部ID。这些唯一的ID是连接共享支持的基础。

    发行版 库名
    Debian / Ubuntu package uuid-dev
    Fedora / CentOS / RHEL package libuuid-devel

    如果libuuid不可用,也可以使用OSSP UUID库:

    发行版 库名
    Debian / Ubuntu package libossp-uuid-dev
    Fedora / CentOS / RHEL package uuid-devel

可选的依赖项

Guacamole的可选依赖项决定了将构建Guacamole服务的哪些部分。这包括对各种远程桌面协议的支持,以及这些协议的任何附加功能:

  • VNC协议支持依赖于libvncclient库,它是libVNCServer的一部分。
  • RDP协议支持依赖于FreeRDP的最新版本(2.0.0或更高版本,但不要使用git中的非发行版本)。
  • SSH协议支持依赖于libss2OpenSSLPango(Guacamole的内置终端模拟器使用的字体呈现和文本布局库)。
  • Telnet协议支持依赖于libtelnetPango
  • Kubernetes协议支持依赖于libwebsocketsOpenSSLPango

guacenc使用程序由guacamole-server提供,用于将屏幕录制转换成视频,它依赖于FFmpeg,并且仅在至少安装了FFmpeg提供的libavcodeclibavformatlibavutillibswscale库的情况下才会被构建。

❗重点:
如果缺少这些依赖项,则依赖它们的功能或协议将无法启用。在决定不安装可选依赖项之前,请仔细阅读本章节。
  • FFmpeg

    在转换Guacamole会话的录像时,guacenc使用FFmpeg提供的libavcodeclibavformatlibavutillibswscale库对视频流进行编码。如果没有FFmpegguacenc实用程序将简单地不被构建。

    如果您不想对Guacamole会话进行图形化录制,或不希望将此类录像转换为视频,则不需要FFmpeg

    发行版 库名
    Debian / Ubuntu package libavcodec-dev, libavformat-dev,
    libavutil-dev, libswsccale-dev
    Fedora / CentOS / RHEL package ffmpeg-devel
  • FreeRDP

    RDP支持需要FreeRDP 2.0.0或更高版本。如果不想构建RDP支持,则不需要此库。

    发行版 库名
    Debian / Ubuntu package freerdp2-dev
    Fedora / CentOS / RHEL package freerdp-devel
  • Pango

    Pango是一个文本布局库,Guacamole使用它为需要终端(Kubernetes、SSH和telnet)的协议呈现文本。如果不希望构建任何基于终端的协议支持,则不需要此库。

    发行版 库名
    Debian / Ubuntu package libpango1.0-dev
    Fedora / CentOS / RHEL package pango-devel
  • libssh2

    SSH和SFTP支持需要libssh2库。如果你不想构建SSH或SFTP支持,则不需要该库。

    发行版 库名
    Debian / Ubuntu package libssh2-1-dev
    Fedora / CentOS / RHEL package libssh2-devel
  • libtelnet

    telnet支持需要libtelnet库。如果不想构建telnet支持,则不需要该库。

    发行版 库名
    Debian / Ubuntu package libtelnet-dev
    Fedora / CentOS / RHEL package libtelnet-devel
  • libVNCServer

    VNC支持需要libVNCServer提供的libvncclient库。如果不想构建VNC支持,则不需要该库。

    发行版 库名
    Debian / Ubuntu package libvncserver-dev
    Fedora / CentOS / RHEL package libvncserver-devel
  • libwebsockets

    Kubernetes支持需要libwebsockets库。如果不想构建Kubernetes支持,则不需要该库。

    发行版 库名
    Debian / Ubuntu package libwebsockets-dev
    Fedora / CentOS / RHEL package libwebsockets-devel
  • PulseAudio

    PulseAudio提供libpulse,Guacamole的VNC支持使用libpulse提供实验性音频支持。如果不打算使用VNC的实验性音频支持,那么就不需要这个库。

    发行版 库名
    Debian / Ubuntu package libpulse-dev
    Fedora / CentOS / RHEL package pulseaudio-libs-devel
  • OpenSSL

    OpenSSL提供SSL和TLS支持,这两种常见的加密方案构成了大部分加密web流量。

    如果安装了libssl,那么guacd将以SSL支持方式构建,从而允许对web应用程序和guacd之间的加密通信。对于SSH支持、操作公钥或私钥、Kubernetes支持以及到Kubernetes服务的SSL/TLS连接,也需要这个库。

    离开SSL支持,就没有guacd加密通信的选项,也无法构建对SSH和Kubernetes的支持。

    发行版 版本
    Debian / Ubuntu package libssl-dev
    Fedora / CentOS / RHEL package openssl-devel
  • libvorbis

    libvorbis为Ogg Vorbis提供支持,Ogg Vorbis是一种免费开放的声音压缩标准。如果安装了libguac,将构建支持Ogg Vorbis,并且支持音频的协议将在可能的情况下使用Ogg Vorbis压缩。

    否则,声音将仅编码为WAV(未压缩),并且仅在浏览器也支持WAV时才可用。

    发行版 库名
    Debian / Ubuntu package libvorbis-dev
    Fedora / CentOS / RHEL package libvorbis-devel
  • libwebp

    libwebplibguac用于WebP图像写入。尽管Guacamole协议没有强制要求支持WebP,但如果浏览器和libguac都支持,则将使用WebP图像。

    由于缺乏WebP支持,Guacamole将只在它更喜欢WebP的情况下使用JPEG。

    发行版 库名
    Debian / Ubuntu package libwebp-dev
    Fedora / CentOS / RHEL package libwebp-devel

获取源代码

你可以从Guacamole项目网站获取guacamole-server源代码的副本。这些版本都是经过充分测试的最新代码的稳定快照,Guacamole团队认为它们适合公众消费者。从项目网站下载的源码都以.tar.gz形式打包,你可以通过以下命令解压:

$ tar -xzf guacamole-server-1.4.0.tar.gz
$ cd guacamole-server-1.4.0/
$

如果你想获得绝对最新版本的源码,且不关心代码是否像稳定版本那样经过充分测试,你也可以通过Guacamole团队的git仓库获取源码:

$ git clone git://github.com/apache/guacamole-server.git
Cloning into 'guacamole-server'...
remote: Counting objects: 6769, done.
remote: Compressing objects: 100% (2244/2244), done.
remote: Total 6769 (delta 3058), reused 6718 (delta 3008)
Receiving objects: 100% (6769/6769), 2.32 MiB | 777 KiB/s, done.
Resolving deltas: 100% (3058/3058), done.
$

构建过程

一旦guacamole-server的源码已经被下载和解压,你需要运行configure脚本。这是一个由GNU Autotools自动生成的shell脚本,GNU Autotools是一个流行的构建系统,Guacamole项目用它来进行guacamole-server的构建。运行configure将确定系统上有哪些库,并根据实际安装的组件选择适当的组件进行构建。

❗重点:
直接从git下载源码将不包含configure脚本,因为自动生成的代码没有包含在项目仓库中。如果直接从项目的git仓库下载代码,则需要手动生成configure脚本:
$ cd guacamole-server/
$ autoreconf -fi
$
进行这项操作需要安装GNU Autotools。
从项目网站下载的源码包已经包含configure脚本和其他必要的构建文件,因此不需要再构建机器上安装GNU Autotools。

运行configure后,您可以看到找到了哪些库,以及它确定应该构建哪些库:

$ ./configure --with-init-dir=/etc/init.d
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...------------------------------------------------
guacamole-server version 1.4.0
------------------------------------------------Library status:freerdp2 ............ yespango ............... yeslibavcodec .......... yeslibavformat ......... yeslibavutil ........... yeslibssh2 ............. yeslibssl .............. yeslibswscale .......... yeslibtelnet ........... yeslibVNCServer ........ yeslibvorbis ........... yeslibpulse ............ yeslibwebsockets ....... yeslibwebp ............. yeswsock32 ............. noProtocol support:Kubernetes .... yesRDP ........... yesSSH ........... yesTelnet ........ yesVNC ........... yesServices / tools:guacd ...... yesguacenc .... yesguaclog .... yesInit scripts: /etc/init.dSystemd units: noType "make" to compile guacamole-server.$

如上所示,--with-init-dir=/etc/init.d指定将guacd的启动脚本构建安装到/etc/init.d目录,以便我们可以在稍后轻松配置guacd开机自启动。如果你不想guacd开机自启动,请关闭--with-init-dir选项。如果你的发行版系统的启动目录不是/etc/init.d,请用正确的目录替换它。你可能需要查阅发行版的文档或在/etc中进行查找以确定正确的位置。

在这里,configure已经找到了一切,包括所有可选库,并将构建所有协议支持,甚至支持RDP中的Ogg Vorbis声音。如果缺少一些库,上面的一些yes回答将显示为no。如果缺少严格要求的库,脚本将彻底失败,你需要安装缺少的依赖项。如果在运行configure后发现缺少对所需内容的支持,只需安装相应的依赖项,然后再次运行configure

❗重点:
所有需要终端的协议(Kubernetes、SSH和telnet)都要求在Guacamole服务器上安装字体才能正常工作,因为终端的输出无法以其他方式呈现。如果未安装字体,对这些协议的支持可以很好的构建,但使用时将无法连接:
# Aug 23 14:09:45 my-server guacd[5606]: Unable to get font "monospace"
如果基于终端的连接不起作用,并且您在syslog中看到这样的消息,您应该确保安装了字体,然后重试。

configure执行完成后,只需键入makeguacamole-server就会编译:

$ make
Making all in src/libguac
make[1]: Entering directory `/home/mjumper/guacamole/guacamole-server/src/libguac'
...
make[1]: Leaving directory `/home/mjumper/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Entering directory `/home/mjumper/guacamole/guacamole-server'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/home/mjumper/guacamole/guacamole-server'
$

在编译所有组件时,屏幕上将滚动输出很多内容。

安装

完成所有操作后,接下来只需键入make install安装生成的组件,然后键入ldconfig更新系统已安装库的缓存:

# make install
Making install in src/libguac
make[1]: Entering directory `/home/mjumper/guacamole/guacamole-server/src/libguac'
make[2]: Entering directory `/home/mjumper/guacamole/guacamole-server/src/libguac'
...
----------------------------------------------------------------------
Libraries have been installed in:/usr/local/libIf you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:- add LIBDIR to the `LD_LIBRARY_PATH' environment variableduring execution- add LIBDIR to the `LD_RUN_PATH' environment variableduring linking- use the `-Wl,-rpath -Wl,LIBDIR' linker flag- have your system administrator add LIBDIR to `/etc/ld.so.conf'See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/mjumper/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Leaving directory `/home/mjumper/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Entering directory `/home/mjumper/guacamole/guacamole-server'
make[2]: Entering directory `/home/mjumper/guacamole/guacamole-server'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/mjumper/guacamole/guacamole-server'
make[1]: Leaving directory `/home/mjumper/guacamole/guacamole-server'
# ldconfig
#

此时,所有东西都已经安装,但guacd并没有运行。在安装了客户端组件后,需要运行guacd才能使用Guacamole。

注意,即使安装了guacd及其启动脚本,你仍可能需要激活该服务才能自动启动。如何激活服务因发行版而异,但每个发行版都会有说明如何做到这一点的文档。

guacamole-client

❗重点:
正常情况下,你不需要构建guacamole-client,因为它是Java编写的并且跨平台的。你可以轻松地从Guacamole项目网站的发行包中获取最新版本的guacamole-client,包括所有支持的扩展,而无需自己构建。如果你不想通过源码构建guacamole-client,只需从Guacamole项目网站下载guacamole.war以及任何所需的扩展,然后跳转到《部署Guacamole》章节。

guacamole-client包含所有Guacamole的Java和JavaScript组件(guacamoleguacamole-commonguacamole-ext以及guacamole-common-js)。这些组件最终构成了Web应用程序,为连接到服务的用户提供HTML5 Guacamole客户端服务。然后该应用程序将连接到guacd,这是guacamole-server的一部分,以便为连接用户提供任何它们有权访问的远程桌面。

编译guacamole-client,需要准备Apache Maven和一份Java SDK副本。多数Linux发行版都有提供相应软件包。

你可以从Guacamole项目网站获取一份guacamole-client的源码副本。这些版本都是经过充分测试的最新代码的稳定快照,Guacamole团队认为适合公众需求。从项目网站下载的源码以.tar.gz形式打包,你可以通过下面的命令解压:

$ tar -xzf guacamole-client-1.4.0.tar.gz
$ cd guacamole-client-1.4.0/
$

guacamole-server一样,如果你想获得绝对最新的代码,且不关心是否经过像稳定版本那样的充分测试,你也可以从Guacamole团队的git仓库中克隆代码。

$ git clone git://github.com/apache/guacamole-client.git
Cloning into 'guacamole-client'...
remote: Counting objects: 12788, done.
remote: Compressing objects: 100% (4183/4183), done.
remote: Total 12788 (delta 3942), reused 12667 (delta 3822)
Receiving objects: 100% (12788/12788), 3.23 MiB | 799 KiB/s, done.
Resolving deltas: 100% (3942/3942), done.
$

guacamole-server不同的是,即使从git仓库获取代码,在构建之前也不需要运行任何东西。在构建之前没有需要生成的脚本,Maven仅需要随源码提供的pom.xml文件。

构建guacamole-client,仅需要运行mvn package。这将调用Maven自动构建和打包所有组件,生成一个单一的.war文件,该文件包含整个Web应用程序。

$ mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] guacamole-common
[INFO] guacamole-ext
[INFO] guacamole-common-js
[INFO] guacamole
[INFO] guacamole-auth-cas
[INFO] guacamole-auth-duo
[INFO] guacamole-auth-header
[INFO] guacamole-auth-jdbc
[INFO] guacamole-auth-jdbc-base
[INFO] guacamole-auth-jdbc-mysql
[INFO] guacamole-auth-jdbc-postgresql
[INFO] guacamole-auth-jdbc-sqlserver
[INFO] guacamole-auth-jdbc-dist
[INFO] guacamole-auth-ldap
[INFO] guacamole-auth-openid
[INFO] guacamole-auth-quickconnect
[INFO] guacamole-auth-totp
[INFO] guacamole-example
[INFO] guacamole-playback-example
[INFO] guacamole-client
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] guacamole-common ................................... SUCCESS [ 21.852 s]
[INFO] guacamole-ext ...................................... SUCCESS [  9.055 s]
[INFO] guacamole-common-js ................................ SUCCESS [  1.988 s]
[INFO] guacamole .......................................... SUCCESS [ 18.040 s]
[INFO] guacamole-auth-cas ................................. SUCCESS [  4.203 s]
[INFO] guacamole-auth-duo ................................. SUCCESS [  2.251 s]
[INFO] guacamole-auth-header .............................. SUCCESS [  1.399 s]
[INFO] guacamole-auth-jdbc ................................ SUCCESS [  1.396 s]
[INFO] guacamole-auth-jdbc-base ........................... SUCCESS [  3.266 s]
[INFO] guacamole-auth-jdbc-mysql .......................... SUCCESS [  4.665 s]
[INFO] guacamole-auth-jdbc-postgresql ..................... SUCCESS [  3.764 s]
[INFO] guacamole-auth-jdbc-sqlserver ...................... SUCCESS [  3.738 s]
[INFO] guacamole-auth-jdbc-dist ........................... SUCCESS [  1.214 s]
[INFO] guacamole-auth-ldap ................................ SUCCESS [  1.991 s]
[INFO] guacamole-auth-openid .............................. SUCCESS [  2.204 s]
[INFO] guacamole-auth-quickconnect ........................ SUCCESS [  2.983 s]
[INFO] guacamole-auth-totp ................................ SUCCESS [  8.154 s]
[INFO] guacamole-example .................................. SUCCESS [  0.895 s]
[INFO] guacamole-playback-example ......................... SUCCESS [  0.795 s]
[INFO] guacamole-client ................................... SUCCESS [  7.478 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:41 min
[INFO] Finished at: 2018-10-15T17:08:29-07:00
[INFO] Final Memory: 42M/379M
[INFO] ------------------------------------------------------------------------
$

一旦Guacamole Web应用程序构建完毕,就可以在相对于当前目录(运行mvn命令的目录)的guacamole/target/子目录看到一个.war文件,准备好部署在Tomcat这样的servlet容器中。

部署Guacamole

Guacamole的web应用程序部分被打包为一个完全独立的.war文件。如果你从Guacamole的主项目网站下载,该文件被命名为guacamole.war。部署它需要将文件复制到你的servlet容器用于.war文件的目录中。对于Tomcat来说,是CATALINA_HOME/webapps/CATALINA_HOME会因Tomcat的安装方式而异,但通常是/var/lib/tomcat/var/lib/tomcat7,或类似的:

cp guacamole.war /var/lib/tomcat/webapps

如果你从源码构建guacamole-client,可以从guacamole/target/目录获取需要的.war文件,该文件带有一个版本后缀。因为Tomcat将通过.war文件的名称确定Web应用程序的位置,你可以在拷贝时简单地将其命名为guacamole.war

cp guacamole/target/guacamole-1.4.0.war /var/lib/tomcat/webapps/guacamole.war

同样,如果你使用不同的servlet容器或Tomcat安装位置不同,你需要检查servlet容器、发行版或两者的文档,以确定guacamole.war文件部署的正确位置。

.war文件放置好后,你需要重启Tomcat以强制Tomcat部署新的web应用程序,如果guacd守护进程尚未运行,则必须启动它。重启Tomcat和guacd的命令将因发行版而异。通常,你可以通过使用restart选项运行相应的初始化脚本来实现重启:

# /etc/init.d/tomcat7 restart
Stopping Tomcat... OK
Starting Tomcat... OK
# /etc/init.d/guacd start
Starting guacd: SUCCESS
guacd[6229]: INFO:  Guacamole proxy daemon (guacd) version 1.4.0 started
#
❗重点:
如果你希望Guacamole开机自启动,你需要配置Tomcat和guacd服务自动运行。你的发行版本会提供相应的配置文档。

在重启Tomcat和guacd后,Guacamole就成功的安装了,但不会完全地运行。在当前状态下,它完全未配置,需要进一步添加至少一个Guacamole用户和几个连接。这将在《配置Guacamole》中介绍。

WebSocket呢?

如果浏览器和你的servlet容器支持WebSocket,Guacamole将会自动使用WebSocket。如果Guacamole无法使用WebSocket连接,它将立即明显地返回到使用HTTP连接。

Guacamole在Tomcat 7.0.37或更高版本,Jetty 8或更高版本以及任何支持JSR 356(WebSocket标准化Java API)的servlet容器中支持WebSocket连接。

【Guacamole中文文档】二、用户指南—— 2.Guacamole源码安装相关推荐

  1. Backtrader官方中文文档:Live Trading实盘交易相关源码翻译

    本文档参考backtrader官方文档,是官方文档的完整中文翻译,可作为backtrader中文教程.backtrader中文参考手册.backtrader中文开发手册.backtrader入门资料使 ...

  2. 【Guacamole中文文档】二、用户指南 —— 3.用Docker安装Guacamole

    用Docker安装Guacamole 可以使用Docker部署Guacamole,无需从源代码构建guacamole-server或手动配置web应用程序.Guacamole项目为Guacamole和 ...

  3. 【Guacamole中文文档】二、用户指南 —— 4.代理Guacamole

    代理Guacamole 像大多数web应用程序一样,Guacamole可以放在反向代理后面.对于Guacamole的生产部署,强烈建议这样做.它提供了灵活性,且如果代理针对SSL进行了正确配置,还可以 ...

  4. 【Guacamole中文文档】二、用户指南 —— 5.配置Guacamole

    配置Guacamole Guacamole安装后,需要配置用户和连接,才能正常工作.本章介绍Guacamole的一般配置及其默认身份验证方法的使用. Guacamole的默认身份验证方法从一个名为us ...

  5. 【Guacamole中文文档】二、用户指南 —— 1.实现和架构

    实现和架构 Guacamole不是一个独立的web应用程序,它由许多部分组成.Web应用程序实际上意在简单和最小化,大部分繁重的工作都由底层组件执行. 用户通过web浏览器连接到Guacamole服务 ...

  6. 【Guacamole中文文档】一、概述 —— 序言

    序言 本书翻译自Apache Guacamole官方手册,英文版由Guacamole项目的上游开发人员编写.这是官方的通用文档,在线版本:http://guacamole.apache.org/ .随 ...

  7. rancher 启动命令_Rancher 中文文档 —— 快速入门指南

    快速入门指南 在本指南中,我们将在一台 Linux 主机上安装 Rancher. 准备一台 Linux 主机 准备一台Linux主机: 使用64位的Ubuntu 16.04,必须有3.10+的内核 至 ...

  8. 如何提高网页中图片显示的用户体验(附源码下载)

    文章中加入适量的图片不仅可以更好的说明和补充文章的内容,而且还可以极大的减缓阅读者在阅读较长篇幅文章时的疲劳和不安.所以图文混排较好的文章能给阅读者更好的用户体验和享受.但是令人遗憾的是很多的网页图片 ...

  9. ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model

    原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...

最新文章

  1. 《LeetCode力扣练习》剑指 Offer 11. 旋转数组的最小数字 Java
  2. java程序里繁体字显示为方块_网页 俄罗斯方块
  3. Codeforces Round 493
  4. jquery ajax 文本丢失加号和连接号的问题
  5. soidworks 生成PCD点云文件
  6. 小红书 “红”到翻车:你的骚操作闪了我的腰?
  7. Android.mk文件官方使用说明
  8. python爬虫英文怎么说_python爬虫腾讯翻译实现中英翻译
  9. 人人接龙助手,三分钟为你的微信群创建打卡活动
  10. 无法启动此程序因为计算机中丢失msvcp140d,msvcp140.dll文件丢失修复工具
  11. mysql大于等于between比较_MySQL范围查询优化,Between与大于等于对比及优化
  12. Hadoop之HDFS的使用
  13. 林瑞c语言代码规范,林瑞庆
  14. 小i机器人登陆美股,乘ChatGPT的东风能走多远?
  15. Linux内核设计与实现(十)| 页高速缓存和页回写
  16. 园林系统优秀党员推荐材料_事迹材料-园林绿化公司党员先进个人事迹材料
  17. 干货丨语雀Baklib在产品帮助手册制作过程中的实际亲测
  18. Android返回上一页面的方式
  19. 修改服务器上tomcat的默认端口号
  20. 游戏开发者的成长之路:C++经典项目控制台贪吃蛇(在GitHub热门项目上增添功能及修改bug)

热门文章

  1. 使用 wget 完成批量下载
  2. 亲眼见证程序员因“一杯牛奶”而改变的生活
  3. win10输入法问题 中英文切换切不出来
  4. 第三方软件测试公司如何选择?2022国内软件测试机构排名
  5. 如何关闭台式计算机休眠,win7台式机怎样关闭电脑休眠模式
  6. 马达监控系统监测电机电压、电流还能做能耗统计,工艺参数监测
  7. 盘古越狱工具 v1.1 官方免费版
  8. 【无关技术】本科毕业设计的一些记录
  9. android 转动360,android指南针罗盘转动是怎么实现的
  10. adb命令刷入kingroot_自己制作可永久伪root精简rom包及刷入教程