Yt.w
2024 年 10 月 27 日午前 6:27
1
lib/highlight_js.rb の以下のコードは、一部のドメインでは機能しますが、他のドメインでは機能しません。
def self.path
"/highlight-js/#{Discourse.current_hostname}/#{version SiteSetting.highlighted_languages}.js"
end
私は2つのDiscourseサイトを持っています。このコードはドメイン www.abc.com では機能しますが、efg.com では機能しません。ブラウザのコンソールで、次のエラーが表示されます。
formatter.js:383 Uncaught (in promise) TypeError: Failed to resolve module specifier '/highlight-js/efg.com/9797975efac87d28baa695ae13ca72ccaf5120f5.js'. The base URL is about:blank because import() is called from a CORS-cross-origin script.
highlight_js.rb の self.path を次のように変更した後:
def self.path
"https://#{Discourse.current_hostname}/highlight-js/#{Discourse.current_hostname}/#{version SiteSetting.highlighted_languages}.js"
end
問題は解決しました。
相対パスの使用
import('/highlight-js/efg.com/9797975efac87d28baa695ae13ca72ccaf5120f5.js')
はCORSの問題を引き起こしますが、絶対URLの使用
import('https://efg.com/highlight-js/efg.com/9797975efac87d28baa695ae13ca72ccaf5120f5.js')
は正常に機能するようです。
「いいね!」 1
abc.comでは動作するのにefg.comでは動作しないのは奇妙ですね。2つの異なるルートは完全に異なるはずなのに:thinking:
Yt.w
2024 年 10 月 27 日午前 9:04
3
www.abc.com では動作しますが、efg.com では動作しません。理由は不明ですが、私のケースで発生しています。
「いいね!」 1
simonk
(Simon King)
2024 年 10 月 28 日午前 11:49
4
これらのサイトのいずれかでCDNを使用していますか?コードのハイライトが私のサイトで機能しなくなったことに気づきましたが、原因はこれだと思います。
The change which made this noticeable was most likely DEV: Modernise highlightjs loading (#24197) · discourse/discourse@0878dde · GitHub , which switched highlightjs to load via native import(), which requires CORS headers when fetching from a CDN.
But even before that change, you likely would have had some issues with things like custom Fonts (which also require CORS headers for cross-origin requests).
In theory, Discourse itself should be adding the CORS header to CDN responses. If it’s not, …
私の場合は、CDNがhighlightjsファイルに対してAccess-Control-Allow-Originヘッダーを返していません。MetaのCDNは、そのヘッダーを含んでいることに気づいたので、何が違うのか疑問に思っています。
$ curl --silent -I https://d3bpeqsaub0i6y.cloudfront.net/highlight-js/meta.discourse.org/9797975efac87d28baa695ae13ca72ccaf5120f5.js | grep -i access-control
access-control-allow-origin: *
access-control-allow-methods: GET, HEAD, OPTIONS
しかし、これらのヘッダーはオリジンサーバーから提供されていません。
$ curl --silent -I https://meta.discourse.org/highlight-js/meta.discourse.org/9797975efac87d28baa695ae13ca72ccaf5120f5.js | grep -i access-control
私の知る限り、Discourseはhighlightjsファイルにaccess-controlヘッダーを追加するように設計されています。
# frozen_string_literal: true
class HighlightJsController < ApplicationController
skip_before_action :preload_json,
:redirect_to_login_if_required,
:redirect_to_profile_if_required,
:check_xhr,
:verify_authenticity_token,
only: [:show]
before_action :apply_cdn_headers, only: [:show]
def show
no_cookies
RailsMultisite::ConnectionManagement.with_hostname(params[:hostname]) do
current_version = HighlightJs.version(SiteSetting.highlighted_languages)
return redirect_to path(HighlightJs.path) if current_version != params[:version]
# note, this can be slightly optimised by caching the bundled file, it cuts down on N reads
しかし、これらのヘッダーはリクエストが「CDNリクエスト」である場合にのみ適用されます。
return unless mini_profiler_enabled?
Rack::MiniProfiler.authorize_request
end
def check_xhr
# bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying
return if !request.get? && (is_api? || is_user_api?)
raise ApplicationController::RenderEmpty.new if !request.format&.json? && !request.xhr?
end
def apply_cdn_headers
if Discourse.is_cdn_request?(request.env, request.method)
Discourse.apply_cdn_headers(response.headers)
end
end
def self.requires_login(arg = {})
@requires_login_arg = arg
end
def self.requires_login_arg
end
mattr_accessor :redis
def self.is_parallel_test?
ENV["RAILS_ENV"] == "test" && ENV["TEST_ENV_NUMBER"]
end
CDN_REQUEST_METHODS ||= %w[GET HEAD OPTIONS]
def self.is_cdn_request?(env, request_method)
return if CDN_REQUEST_METHODS.exclude?(request_method)
cdn_hostnames = GlobalSetting.cdn_hostnames
return if cdn_hostnames.blank?
requested_hostname = env[REQUESTED_HOSTNAME] || env[Rack::HTTP_HOST]
cdn_hostnames.include?(requested_hostname)
end
def self.apply_cdn_headers(headers)
これは、Discourseが「CDNリクエスト」用に別のホスト名で構成されている場合にのみ機能します。
「いいね!」 1
simonk
(Simon King)
2024 年 10 月 28 日午後 12:02
5
cdn_origin_hostname という設定があり、おそらく通常の Discourse ホスト名に設定できる可能性があります。
# authorization key that will be included as a header in requests made by the
# snapshots transporter to the URL specified above. The destination should
# know this key and only accept requests that have this key in the
# `Mini-Profiler-Transport-Auth` header.
mini_profiler_snapshots_transport_auth_key =
# recommended, cdn used to access assets
cdn_url =
# The hostname used by the CDN to request assets
cdn_origin_hostname =
# comma delimited list of emails that have developer level access
developer_emails =
# redis server address
redis_host = localhost
# redis server port
redis_port = 6379
これにより is_cdn_request チェックがパスすると思いますが、副作用があるかどうかはわかりません。
Yt.w
2024 年 10 月 28 日午後 12:48
6
はい、efg.comでCDNを使用していますが、jsファイルにアクセスすると、正しいAccess-Control-Allow-Origin が返されます。それが私を非常に混乱させています。
simonk
(Simon King)
2024 年 10 月 29 日午後 5:48
7
フォローアップとして、cdn_origin_hostname を通常の Discourse インスタンスのドメイン名に設定し、CDN キャッシュをフラッシュしたところ、highlightjs が再び動作するようになりました。まだ副作用は気づいていません …
cuo_wu
(cuo wu)
2025 年 5 月 18 日午前 11:34
8
私もこの問題に直面しています。何かアップデートはありますか?