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

Rails session在Chrome 67及更低版本中无法持久化问题排查

问题根因

Chrome 67及更低版本session无法持久化的问题,是Fetch API的默认配置差异导致的:

  • Chrome 68及以上版本,Fetch API的credentials参数默认值为same-origin,同源请求会自动携带、存储Cookie
  • Chrome 67及更低版本,Fetch API的credentials参数默认值为omit,所有请求默认不会携带、也不会存储响应返回的Cookie
    Rails的session默认依赖Cookie存储,POST请求设置session后返回的Set-Cookie响应头在低版本Chrome中被忽略,后续GET请求也不会携带session Cookie,因此读取不到之前设置的session值。

解决方案

修改前端Fetch请求配置,显式指定credentials参数即可:

fetch('/api/set', { 
  method: 'POST',
  credentials: 'same-origin' // 新增这一行
}) 
  .then((r) => r.json())
  .then((r) => {
    console.log('SET: ', r);
    fetch('/api/get', {
      credentials: 'same-origin' // GET请求也需要添加该配置
    })
      .then((r) => r.json())
      .then((r) => console.log('GET: ', r));
  });

修改后在所有Chrome版本中都能正常读写session。

复现说明(供排查参考)

最小复现项目可按以下步骤运行:

  1. 将如下代码保存为config.ru文件:
require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'
  gem 'rails', '~> 5.0.6'
end

require 'rails'
require 'action_controller/railtie'

class TestApp < Rails::Application
  config.eager_load = 'development'
  config.consider_all_requests_local = true
  config.secret_key_base = '669846b267cea64315663e4f5c124096'
  config.secret_token = '9c9846b2f7cea64315503e4f5c124094'

  routes.append do
    get '/' => 'api#index'
    post '/api/set' => 'api#set'
    get '/api/get' => 'api#get'
  end
end

class ApiController < ActionController::Base
  HTML_STRING = <<-EOF
    <script>
      fetch('/api/set', { method: 'POST' })
        .then((r) => r.json())
        .then((r) => {
          console.log('SET: ', r);
          fetch('/api/get')
            .then((r) => r.json())
            .then((r) => console.log('GET: ', r));
        });
    </script>
  EOF

  def index
    render :html => HTML_STRING.html_safe
  end

  def set 
    session[:x] = 'x'
    render :json => { :x => session[:x] }
  end

  def get
    render :json => { :x => session[:x] }
  end
end

TestApp.initialize!

run TestApp
  1. 执行命令启动服务:rackup -p 3030
  2. 不同版本Chrome访问后的控制台输出差异:
    • Chrome 68+:
    SET:  {x: 'x'}
    GET:  {x: 'x'}
    
    • Chrome 67及更低版本:
    SET:  {x: 'x'}
    GET:  {x: null}
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:36:04