網站首頁 編程語言 正文
背景
在源網頁通過服務器重定向打開某個三方網頁,網絡層出現了 -1005 (NSURLErrorNetworkConnectionLost) 錯誤碼,排查差異后發現是由于給這個三方服務帶了源網頁特有的 HTTP Header,導致服務器檢查異常從而斷開連接。
核心原因是跨域重定向場景透傳了 Header 帶到了三方服務,這有些不符合常理,會帶來兩個明顯的問題:
- 敏感 HTTP Header 傳遞給三方服務,存在隱私安全問題;
- 服務收到未預期的 HTTP Header,可能被視為非法訪問,導致網頁異常;
系統庫如何設計的
NSURLSession 在跨域重定向場景默認會透傳 HTTP Header,參考 Swift 在 _HTTPURLProtocol 的相關處理:
/// If the response is a redirect, return the new request /// RFC 7231 section 6.4 defines redirection behavior for HTTP/1.1 /// - SeeAlso: <https://tools.ietf.org/html/rfc7231#section-6.4> func redirectRequest(for response: HTTPURLResponse, fromRequest: URLRequest) -> URLRequest? { //TODO: Do we ever want to redirect for HEAD requests? guard let location = response.value(forHeaderField: .location), let targetURL = URL(string: location) else { // Can't redirect when there's no location to redirect to. return nil } var request = fromRequest // Check for a redirect: switch response.statusCode { case 301...302 where request.httpMethod == "POST", 303: // Change "POST" into "GET" but leave other methods unchanged: request.httpMethod = "GET" request.httpBody = nil case 301...302, 305...308: // Re-use existing method: break default: return nil } // If targetURL has only relative path of url, create a new valid url with relative path // Otherwise, return request with targetURL ie.url from location field guard targetURL.scheme == nil || targetURL.host == nil else { request.url = targetURL return request } … (后面是相對路徑處理) }
大致處理流程為:
- 取出響應頭 Location 字段作為目標 URL;
- 若為 POST 請求改為 GET 請求并清空其 Body;
- 若目標 URL 為相對路徑,補齊完整 URL;
可以看到重定向后的請求會直接繼承 HTTP Header,這個處理遵循了 RFC 7231 的規范,大致去翻了一下,只描述了 Location header field 的處理方法,而沒有說明其它請求頭該如何處理,在 Chrome 下重定向場景應該是直接丟棄之前的 Header 的。
我們知道有一個公開代理方法…willPerformHTTPRedirection…
可以去改變重定向請求,但如果不借助網絡攔截技術,WebKit 里面的請求也無法修改,順便看一下 WebKit 內部是否對這種場景有所處理。
WebKit 是在 NetworkSessionCocoa 類里面承載 NSURLSession 請求的,實現了URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:
協議,順著處理鏈路從 Network 進程跟到 Web 進程再跟到 APP 進程,都沒有找到關于跨域重定向清理 HTTP Header 的處理,更不用說公開配置能力了。
解決方案
針對 WebView 需要跨域重定向的場景,如何避免私有 HTTP Header 傳遞給目標請求服務?
方案一
如果前置請求是為了做統計上報,那可以直接跳轉到目標 URL,前置請求旁路去處理;如果前置請求是為了獲取跳轉的地址,那么可以發起一個 Ajax 請求拿到回包后去跳轉目標 URL。
或者更直接的,把 server-side redirect 改為 client-side redirect,讓前置請求返回文檔,文檔內部進行document.replace()
等函數跳轉到目標 URL,但這種處理會讓性能劣化,并且會導致前置請求關聯的 Web 進程歷史棧緩存被清理
核心思想就是避免服務器跨域重定向,由于和 Chrome 內核表現不一致且前端改造成本較大,一般較難實施,但這對于沒有 WebKit 網絡攔截技術的 APP 來說可能是唯一思路。
方案二
如果有 WebKit 網絡攔截技術,那處理就比較簡單了,只需要保證在重定向請求發起之前,如果主域名發生變化,就把 APP 私有的請求頭清理掉,較簡單的規避系統設計問題。
原文鏈接:https://juejin.cn/post/7170998701853245447
相關推薦
- 2024-01-14 npm install時 cannot read properties of null的問題
- 2022-05-27 Redis對批量數據實現分布式鎖的實現代碼_Redis
- 2022-10-14 WebSecurityConfigurerAdapter已棄用
- 2023-05-31 Pandas使用分隔符或正則表達式將字符串拆分為多列_python
- 2022-07-16 Spring MVC重定向和轉發
- 2022-04-08 go實現圖片拼接與文字書寫的方法實例_Golang
- 2022-05-06 python 實現兩個excel表格數據的對比
- 2022-08-27 一文了解Go語言中的函數與方法的用法_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支