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

使用scalaj.http 2.4发送If-None-Match请求未返回304状态码问题

解决scalaj.http 2.4中If-None-Match头无法触发304响应的问题

我之前也踩过类似的坑,结合GitHub API的特性和scalaj.http的行为,主要有几个关键点需要调整:

核心问题分析

你的代码里有两个容易被忽略的细节,导致服务器没有返回预期的304:

  1. User-Agent不符合要求或不一致:GitHub API强制要求请求必须包含有意义的User-Agent头(比如你的GitHub用户名或应用名称)。如果两次请求的User-Agent不同,或者使用了scalaj.http的默认值(可能存在隐性变化),服务器会将其视为不同客户端的请求,不会触发缓存校验返回304。

  2. ETag值传递有误:你手动写死了ETag值,但实际应该从第一次请求的响应中直接获取并复用,确保完全匹配(包括前后的双引号)。手动输入的ETag可能和服务器返回的不一致,或者存在转义问题。

修正后的代码示例

下面是调整后的代码,确保两次请求的一致性并正确复用ETag:

import scalaj.http.Http

object EtagTest extends App {
  // 定义统一的请求模板,保证所有固定请求头一致
  val githubRequest = Http("https://api.github.com/users/octocat/orgs")
    .header("User-Agent", "your-github-username") // 替换成你的GitHub用户名或应用名
    .header("Accept", "application/vnd.github.v3+json") // 符合GitHub API的Accept格式要求

  // 第一次请求获取ETag
  val firstResponse = githubRequest.asString
  val etag = firstResponse.header("ETag").getOrElse("")
  println(s"获取到的ETag: $etag")

  // 第二次请求携带正确的If-None-Match头
  val cachedResponse = githubRequest
    .header("If-None-Match", etag)
    .asString

  println(s"响应状态码: ${cachedResponse.code}") // 现在应该返回304
}

关键调整说明

  • 统一请求头:把所有固定的请求头(User-Agent、Accept)放到基础请求模板中,确保两次请求的头完全一致。GitHub API对Accept头也有要求,指定application/vnd.github.v3+json能避免格式差异导致的缓存失效。
  • 复用ETag:直接从第一次响应中提取ETag值,不要手动拼接或修改,这样能保证和服务器返回的校验值完全匹配。
  • 验证请求一致性:如果还是有问题,可以打印两次请求的所有头信息,确认没有隐性差异:
    println("第一次请求头: " + githubRequest.headers)
    println("第二次请求头: " + githubRequest.header("If-None-Match", etag).headers)
    

额外注意事项

scalaj.http 2.4版本的默认User-Agent是scalaj-http/2.4.0,虽然可以用,但GitHub更推荐使用能识别你的客户端的名称,避免被限流或拒绝请求。另外,确保你的网络环境没有代理或缓存服务器篡改请求头,这也可能导致304响应不触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:39:25