当前位置: 代码网 > it编程>App开发>苹果IOS > NSURLSession跨域重定向透传HTTP Header问题解决

NSURLSession跨域重定向透传HTTP Header问题解决

2024年05月18日 苹果IOS 我要评论
背景在源网页通过服务器重定向打开某个三方网页,网络层出现了 -1005 (nsurlerrornetworkconnectionlost) 错误码,排查差异后发现是由于给这个三方服务带了源网页特有的

背景

在源网页通过服务器重定向打开某个三方网页,网络层出现了 -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 私有的请求头清理掉,较简单的规避系统设计问题。

以上就是nsurlsession跨域重定向透传http header问题解决的详细内容,更多关于nsurlsession跨域重定向的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com