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

Play Framework 2.6(Scala)内联JavaScript无法运行遇CSP报错求助

Fixing Inline JavaScript CSP Error in Play Framework 2.6 + Scala

Got it, let's break down how to fix that Content Security Policy (CSP) error you're seeing. Play Framework 2.6+ enables a strict default CSP to protect against XSS attacks, which is why your inline JavaScript is getting blocked. Here are the three most common solutions, ordered by security best practice:

A nonce is a unique, random value generated per request—this is the most secure approach because only scripts with the matching nonce will execute.

Step 1: Generate the Nonce in Your Controller

Add code to create a secure nonce and attach it to both the response header and your template:

import play.api.mvc._
import java.security.SecureRandom
import java.util.Base64

class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
  // Reuse a secure random instance for efficiency
  private val secureRandom = new SecureRandom()

  def index() = Action { implicit request: MessagesRequest[AnyContent] =>
    // Generate a 16-byte nonce, base64-encoded
    val nonce = Base64.getEncoder.encodeToString(new Array[Byte](16))
    // Pass the nonce to your template and set the CSP header
    Ok(views.html.index(nonce)).withHeaders(
      CONTENT_SECURITY_POLICY -> s"default-src 'self'; script-src 'self' 'nonce-$nonce';"
    )
  }
}

Step 2: Reference the Nonce in Your HTML Template

Add the nonce attribute to your inline script tag, using the value passed from the controller:

<script nonce="@nonce">
  // Your inline JavaScript here
  console.log("Inline script now runs with nonce!");
</script>

2. Use a Script Hash (For Static Inline Scripts)

If your inline script never changes, you can use its SHA-256 hash (which the error message already provided: sha256-DdH/amfJizOgk2xZ+Xst5j13qHxPYrrrfT6x/TzfYiA=).

Update Your Controller's CSP Header

Add the hash to the script-src directive:

def index() = Action { implicit request: MessagesRequest[AnyContent] =>
  Ok(views.html.index()).withHeaders(
    CONTENT_SECURITY_POLICY -> "default-src 'self'; script-src 'self' 'sha256-DdH/amfJizOgk2xZ+Xst5j13qHxPYrrrfT6x/TzfYiA=';"
  )
}

Note: If you modify the inline script later, you'll need to recalculate the hash and update the CSP.

3. Use unsafe-inline (Only for Development)

⚠️ Never use this in production—it disables a key security layer against XSS attacks. This is only for quick testing in a local dev environment:

def index() = Action { implicit request: MessagesRequest[AnyContent] =>
  Ok(views.html.index()).withHeaders(
    CONTENT_SECURITY_POLICY -> "default-src 'self'; script-src 'self' 'unsafe-inline';"
  )
}

Bonus: Global CSP Configuration

Instead of setting the CSP header per controller, you can define a base policy in application.conf, though you'll still need to inject dynamic values like nonces in controllers:

play.filters.headers.contentSecurityPolicy = "default-src 'self'; script-src 'self'"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:21:20