概述

超链接服务是一个服务器端组件,提供链接验证和媒体嵌入解析功能。它运行在主机基础设施内的本地环境中,为 TinyMCE 编辑器中的 链接检查器 插件(用于验证链接)和 增强型媒体嵌入 插件(将媒体 URL 解析为可嵌入内容)提供支持。部署后,每个插件必须单独配置以连接到此服务。

在本地运行超链接服务的唯一要求是具备容器运行时或编排工具,例如 Docker、Kubernetes 或 Podman。

访问 Tiny Cloud Docker 镜像仓库并拉取 Docker 镜像需要有效的访问令牌。请联系 Tiny 支持团队 申请访问令牌。

将此 Docker 镜像推送到公共容器注册表违反了 Tiny 自托管软件许可协议,包括:

要求

  • 已安装并正在运行 Docker Engine。

  • 用户具有管理员或 Root 用户权限以运行 Docker 命令。

  • 用户满足以下条件之一:

安装

为了从 Tiny Cloud Docker 注册表获取本地服务镜像,必须拥有有效的访问令牌。联系 Tiny 支持团队 以申请访问令牌。

获取 Docker 镜像

  1. 登录 Tiny Cloud Docker 注册表:

    docker login -u tiny -p [access-token] registry.containers.tiny.cloud
  2. 从 Docker 注册表拉取镜像:

    docker pull registry.containers.tiny.cloud/hyperlinking-tiny:<VERSION>

    将 <VERSION> 替换为 latest 或特定版本号。

目前,Docker 镜像仅支持 x86-64(也称为 AMD64)架构的处理器。

指定配置

完成上述步骤后,运行从拉取的镜像启动的 Docker 容器:

docker run -p 19100:19100 registry.containers.tiny.cloud/hyperlinking-tiny:<VERSION>

此命令触发 -p 19100:19100,在 localhost:19100 上暴露服务。服务在 Docker 容器内运行于端口 19100,并将其映射到您本地机器的相同端口。

如果设置正确,日志应显示类似以下内容的输出:

2025-09-15 04:46:17 [io-compute-3] INFO  navi - navi
...
2025-09-15 04:46:17 [io-compute-blocker-3] INFO  navi - -> Raw Config assembled from various sources: ConfigOrigin(merge of /app/application.conf: 1,system properties,reference.conf @ jar:file:/app/navi.jar!/reference.conf: 1)
2025-09-15 04:46:17 [io-compute-blocker-3] WARN  c.e.d.config.AllowedOriginsConfig$ - No allowed-origins specified in config!
2025-09-15 04:46:17 [io-compute-blocker-3] WARN  c.e.d.config.AllowedOriginsConfig$ - No allowed-origins specified in config!
2025-09-15 04:46:17 [io-compute-blocker-3] INFO  navi - navi config loaded successfully: NaviConfig(LinkCheckerConfig(true,ReturnUnknown),true,CacheConfig(10000,86400 seconds,3600 seconds),SdkServiceWithClientConfig(HttpConfig(100,10,10,3,HttpConfigTimeouts(10,10,10),JvmTrustModel()),None,OriginWhitelist(List(),OriginPrecision(true))),SelfHostedMediaSourcesConfig(CustomEmbedPlugins(UrlTrie(Branch(None,TreeMap()),Branch(None,TreeMap()))),None),OriginWhitelist(List(),OriginPrecision(true)),Logger[navi])
2025-09-15 04:46:18 [io-compute-blocker-3] INFO  o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:19100
2025-09-15 04:46:18 [io-compute-blocker-3] INFO  o.h.blaze.server.BlazeServerBuilder -
  _   _   _        _ _
 | |_| |_| |_ _ __| | | ___
 | ' \  _|  _| '_ \_  _(_-<
 |_||_\__|\__| .__/ |_|/__/
             |_|
2025-09-15 04:46:18 [io-compute-blocker-3] INFO  o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:19100/

运行此命令将生成关于未配置 allowed-origins 的日志警告。这是预期的行为,将在下一步中进行设置。

TinyMCE 服务器端组件需要一个配置文件才能正常运行。按照惯例,该文件命名为 application.conf。更多信息,请参阅 服务器端组件所需配置。

此配置文件至少需要包含以下信息:

  • allowed-origins - 指定允许与服务器端编辑器功能通信的域。这对于所有服务器端组件都是强制性的。

以下针对高级版服务器端组件的设置是可选的,并将适用于使用配置文件发出 HTTP/HTTPS 请求的所有服务。

以下针对超链接高级版服务器端组件的设置是可选的:

增强型媒体嵌入服务允许使用自定义 Iframely 账户、配置的 oEmbed 端点,或两者结合。如果 URL 没有 Iframely 或 oEmbed 配置,服务将生成摘要卡片。

摘要卡片是基于 URL 处检测到的可用元数据和内容创建的可嵌入代码片段。这确保了即使未配置任何预定义的嵌入方法,服务仍能提供结构化和视觉上一致的媒体表示。

当媒体插入到内容中时,服务遵循以下顺序:

  1. 检查 URL 是否匹配任何自定义 oEmbed 配置。如果失败,

  2. 如果配置了 Iframely,则查询 Iframely API。如果未配置 Iframely,

  3. 创建摘要卡片。

以下针对增强型媒体嵌入服务的设置是可选的:

运行 Docker 容器

Docker 容器也可以使用 docker compose 运行。在此示例中,假设目录结构如下:

hyperlinking-service/
├── application.conf
└── docker-compose.yaml

以下是包含基本配置的 application.conf 文件示例:

ephox {

  allowed-origins {
    origins = [
      "http://example.com",
      "http://good.com",
      "*.my.company.org"
    ]
  }

}

准备好应用程序配置文件后,继续执行 Docker Compose 设置以配置和运行服务。

  1. 创建 docker-compose.yaml 文件:

    services:
      hyperlinking-tiny:
        image: registry.containers.tiny.cloud/hyperlinking-tiny:<VERSION>
        ports:
          - "19100:19100"
        restart: always
        init: true
        volumes:
          - type: bind
            source: ./application.conf #change this to the path on your local machine
            # Use the below target path if using any version below 2.109.6.
            # target: /ephox-hyperlinking/ephox-hyperlinking-docker-env.conf
            target: /app/application.conf
            read_only: true
从版本 2.109.6 开始,volumes 选项中的 target 路径必须指向 /app/application.conf。
  • 运行服务(在放置 docker-compose.yaml 的同一目录内):

    docker compose up

    如果设置正确,初始化日志应如下所示:

    ✔ Container hyperlinking-tiny-hyperlinking-tiny-1                                                                                                                         Created        0.1s
    Attaching to hyperlinking-tiny-1
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-7] INFO  navi - navi
    ...
    -> Found value for property: /app/application.conf
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -       * Parsing config defined by /app/application.conf from property: ephox.config.file
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -         -> Processing file: /app/application.conf
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -   * External application.conf => /opt/ephox/application.conf
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -     * Optional File (/opt/ephox/application.conf). Defaults to empty if file not found
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi - * Internal Configuration
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -   -> No extra internal configuration specified - skipping
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi - * Default (Reference) Configuration
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi -   * Loading configuration files from classpath (reference.conf and integration.conf). Neither is required.
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi - -> Raw Config assembled from various sources: ConfigOrigin(merge of /app/application.conf: 1,system properties,reference.conf @ jar:file:/app/navi.jar!/reference.conf: 1)
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  c.e.d.config.AllowedOriginsConfig$ - Read allowed-origins config (ignoring ports = true) as:
    hyperlinking-tiny-1  |  - localhost:8000
    hyperlinking-tiny-1  |  - example.com
    hyperlinking-tiny-1  |  - good.com
    hyperlinking-tiny-1  |  - my.company.org
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  c.e.d.config.AllowedOriginsConfig$ - Read allowed-origins config (ignoring ports = true) as:
    hyperlinking-tiny-1  |  - localhost:8000
    hyperlinking-tiny-1  |  - example.com
    hyperlinking-tiny-1  |  - good.com
    hyperlinking-tiny-1  |  - my.company.org
    hyperlinking-tiny-1  | 2025-09-15 04:57:29 [io-compute-blocker-7] INFO  navi - navi config loaded successfully: NaviConfig(LinkCheckerConfig(true,ReturnUnknown),true,CacheConfig(10000,86400 seconds,3600 seconds),SdkServiceWithClientConfig(HttpConfig(100,10,10,3,HttpConfigTimeouts(15,15,15),JvmTrustModel()),None,OriginWhitelist(List(localhost:8000, example.com, good.com, my.company.org),OriginPrecision(true))),SelfHostedMediaSourcesConfig(CustomEmbedPlugins(UrlTrie(Branch(None,TreeMap()),Branch(None,TreeMap(org -> Branch(None,TreeMap(wikipedia -> Branch(None,TreeMap(en -> Branch(Some(PathMatcher(List((wiki/.*,WikipediaEmbedPlugin(https://en.wikipedia.org/w/api.php,10))))),TreeMap()))))))))),None),OriginWhitelist(List(localhost:8000, example.com, good.com, my.company.org),OriginPrecision(true)),Logger[navi])
    hyperlinking-tiny-1  | 2025-09-15 04:57:30 [io-compute-blocker-7] INFO  o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:19100
    hyperlinking-tiny-1  | 2025-09-15 04:57:30 [io-compute-blocker-7] INFO  o.h.blaze.server.BlazeServerBuilder -
    hyperlinking-tiny-1  |   _   _   _        _ _
    hyperlinking-tiny-1  |  | |_| |_| |_ _ __| | | ___
    hyperlinking-tiny-1  |  | ' \  _|  _| '_ \_  _(_-<
    hyperlinking-tiny-1  |  |_||_\__|\__| .__/ |_|/__/
    hyperlinking-tiny-1  |              |_|
    hyperlinking-tiny-1  | 2025-09-15 04:57:30 [io-compute-blocker-7] INFO  o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:19100/
  • 后续步骤

    1. 通过 cURL 命令测试服务

      为了验证 Hyperlinking 服务已在容器内正确设置并正常运行,请确保服务正在端口 19100 上运行。一旦激活,它应该准备好接收请求。以下预期输出确认了配置是否正确,假设 http://good.com 在允许的源列表中,而 http://bad.com 不在。

      要检查服务是否正在运行,请使用:

      curl http://localhost:19100/version

      示例输出为:2.109.0

      要确认请求已发送至 Link Checker 服务,请使用:

      curl --location 'http://localhost:19100/1/check' \
      --header 'Origin: http://good.com' \
      --header 'Content-Type: application/json' \
      --data '{ "urls": [{"url":"http://google.com"}, {"url": "http://youtube.com"}, {"url":"http://google.com/404"}, {"url":"https://ephox.."}]}'

      最后,要验证请求是否因未授权且来自错误的源而被拒绝,请使用:

      curl --location 'http://localhost:19100/1/check' \
      --header 'Origin: http://bad.com' \
      --header 'Content-Type: application/json' \
      --data '{ "urls": [{"url":"http://google.com"}, {"url": "http://youtube.com"}, {"url":"http://google.com/404"}, {"url":"https://ephox.."}]}'

      如果出现错误,预期的消息是:{ "message": "The supplied authentication is not authorized to access this resource" }。

    2. 在 TinyMCE 中直接测试

      在部署之前,建议在 TinyMCE 编辑器内部测试此服务。

      为此,请在编辑器中配置 Link Checker 和 Enhanced Media Embed 功能,并通过 tinymce.init 调用它们。如果在默认端口 19100 上本地运行,请使用以下设置:

      tinymce.init({
        selector: 'textarea', // change this value according to your HTML
        plugins: 'code image link linkchecker autolink code',
        toolbar: 'image link code',
        linkchecker_service_url: "http://localhost:19100",
        mediaembed_service_url: "http://localhost:19100"
      });