设置SameSite=None后Javascript仍无法获取Set-Cookie头问题
针对你遇到的Set-Cookie头可见但JS无法读取、后续请求不携带Cookie的问题,给你几个排查和解决方向:
1. 强制fetch请求携带凭证
fetch默认的credentials配置是same-origin,如果Cordova WebView和Drupal域名不同,必须显式设置credentials: 'include',否则WebView不会存储Cookie,也不允许JS读取Set-Cookie:
fetch('https://你的Drupal域名/user/login', { method: 'POST', credentials: 'include', // 关键配置 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'name=xxx&pass=xxx&form_id=user_login_form' })
2. 确认Cookie的Secure属性
SameSite=None 必须搭配Secure属性,否则浏览器(包括Cordova WebView)会直接拒绝存储这个Cookie。检查Drupal返回的Set-Cookie头,必须包含Secure; SameSite=None,比如:
Set-Cookie: SESSxxxx=xxx; expires=Wed, 13-Sep-2023 00:00:00 GMT; Max-Age=2000000; path=/; domain=你的Drupal域名; secure; HttpOnly; SameSite=None
如果没有Secure,去Drupal的Cookie Same Site模块里确认配置,或者修改settings.php强制开启:
$settings['session.cookie_secure'] = TRUE;
3. 调整Cordova WebView的Cookie权限
Android端
- 在
config.xml中添加WebView配置,允许第三方Cookie:
<preference name="AndroidInsecureFileModeEnabled" value="true" /> <preference name="OverrideUserAgent" value="Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36" />
- Android 12+需要额外开启第三方Cookie支持,可以通过原生代码修改WebSettings:
WebSettings webSettings = webView.getSettings(); webSettings.setThirdPartyCookiesEnabled(true);
iOS端
- WKWebView对第三方Cookie限制严格,安装
cordova-plugin-wkwebview-cookie-sync插件同步Cookie:
cordova plugin add cordova-plugin-wkwebview-cookie-sync
- 在
config.xml中添加权限配置:
<preference name="AllowFileAccessFromFileURLs" value="true" /> <preference name="AllowUniversalAccessFromFileURLs" value="true" />
- iOS 14+如果用HTTP测试,需要在
Info.plist中添加例外(生产环境必须用HTTPS):
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
4. 避免使用file://协议(核心建议)
Cordova默认用file://加载本地页面,这种协议下Cookie的跨域处理会有很多兼容性问题。建议改用本地HTTP服务器映射页面:
- 安装
cordova-plugin-ionic-webview:
cordova plugin add cordova-plugin-ionic-webview
- 在
config.xml中配置Scheme和Hostname:
<preference name="Scheme" value="https" /> <preference name="Hostname" value="localhost" />
这样本地页面会以https://localhost的形式加载,和Drupal的域名跨域时,配合credentials: 'include'就能正常处理Cookie。
5. 排查Drupal的Session配置
- 确认
settings.php中的session.cookie_domain设置正确,要匹配你的Drupal域名,比如:
$settings['session.cookie_domain'] = '.your-drupal-domain.com';
- 不用纠结JS能不能读取Cookie:如果Cookie带
HttpOnly属性,JS确实无法直接读取,但这不影响后续请求自动携带Cookie——只要WebView存储了Cookie,请求就会自动带上,重点看后续请求的Request Headers里有没有Cookie字段即可。
内容的提问来源于stack exchange,提问作者Francesco Marchetti-Stasi

