You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发环境下Content Security Policy导致Rails错误页面失效

解决Rails开发环境下CSP阻止错误页面内联JS/CSS的问题

我的Rails应用已启用Content Security Policy(CSP),本地开发环境运行时,Rails错误页面因浏览器CSP阻止内联JavaScript和CSS无法正常显示。Chrome中turbo.es2017-esm.js报出如下错误:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' localhost:3000 'nonce-vJgPXpdJcQ60SidkuK6V/Q=='". Either the 'unsafe-inline' keyword, a hash ('sha256-N8P082RH9sZuH82Ho7454s+117pCE2iWh5PWBDp/T60='), or a nonce ('nonce-...') is required to enable inline execution.

查看页面元素发现错误页面的script标签nonce属性为空:

<script type="text/javascript" data-template="error_page" nonce="">

当前配置文件

config/initializers/content_security_policy.rb

Rails.application.configure do
  # The policies are set in config/environments/[development/test/production].rb

  # Generate random nonce that will be used in <script> and <style> elements
  config.content_security_policy_nonce_generator = -> (request) { SecureRandom.base64(16) }

  # Add the nonce to the Content-Security-Policy header
  config.content_security_policy_nonce_directives = %w(script-src style-src)
end

config/environments/development.rb

config.content_security_policy do |policy|
  policy.default_src :self
  policy.img_src :self, 'data:'
  policy.script_src  :self
  policy.style_src   :self
  policy.connect_src :self
end

版本信息

  • Rails: 7.0.4.2
  • turbo-rails: 1.3.3
  • JavaScript依赖:@hotwired/turbo-rails:7.2.5、@hotwired/turbo:7.2.5、@hotwired/stimulus:3.2.1

解决办法

1. 自定义错误页面布局,确保nonce注入

Rails默认错误页面渲染时未经过常规视图流程,导致nonce未正确赋值。可以创建自定义错误布局:

在app/views/layouts/下新建error.html.erb,参考主布局结构并确保脚本标签使用content_security_policy_nonce辅助方法:

<!DOCTYPE html>
<html>
<head>
  <title>Error</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <script nonce="<%= content_security_policy_nonce %>" src="<%= asset_path 'turbo.es2017-esm.js' %>" type="module"></script>
</head>
<body>
  <%= yield %>
</body>
</html>

2. 临时放宽开发环境CSP规则(仅限开发)

如果不想自定义布局,可以在开发环境CSP中添加unsafe-inline(生产环境禁止使用),或者使用错误页面内联脚本的哈希值:

方案A:添加unsafe-inline
修改config/environments/development.rb:

config.content_security_policy do |policy|
  policy.default_src :self
  policy.img_src :self, 'data:'
  policy.script_src  :self, 'unsafe-inline'
  policy.style_src   :self, 'unsafe-inline'
  policy.connect_src :self
end

方案B:使用脚本哈希值
从Chrome错误提示中提取哈希值,添加到script-src:

config.content_security_policy do |policy|
  policy.default_src :self
  policy.img_src :self, 'data:'
  policy.script_src  :self, 'sha256-N8P082RH9sZuH82Ho7454s+117pCE2iWh5PWBDp/T60='
  policy.style_src   :self
  policy.connect_src :self
end

3. 验证nonce生成逻辑

在初始化器中添加日志,确认错误请求是否生成nonce:
修改config/initializers/content_security_policy.rb:

config.content_security_policy_nonce_generator = -> (request) {
  nonce = SecureRandom.base64(16)
  Rails.logger.debug "Generated nonce: #{nonce} for request path: #{request.path}"
  nonce
}

重启服务器后,查看日志确认错误请求(如/500)是否有nonce生成记录。


内容的提问来源于stack exchange,提问作者Evgenii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:20:55