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

如何通过短链接获取完整URL?iOS端百度地图短链接解析方案

解析百度地图短链接获取完整URL(iOS实现)

嘿,这个需求我之前处理过类似的短链接解析场景,其实核心逻辑就是追踪HTTP重定向——百度的短链接本质是返回302跳转响应,浏览器会自动跟进跳转拿到最终URL,咱们在iOS里手动实现这个逻辑就搞定了。下面给你两种可行的Swift方案:

方案1:通过URLSession代理追踪重定向

这种方式适合需要监听每一步跳转的场景,能灵活控制跳转流程:

import UIKit

class ShortLinkResolver: NSObject, URLSessionDataDelegate {
    func resolveBaiduShortLink(_ shortURL: URL, completion: @escaping (URL?) -> Void) {
        let sessionConfig = URLSessionConfiguration.default
        // 初始化带代理的URLSession
        let session = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue.main)
        
        var request = URLRequest(url: shortURL)
        // 模拟移动端浏览器的User-Agent,避免被百度拦截
        request.setValue("Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", forHTTPHeaderField: "User-Agent")
        
        // 把回调闭包存在taskDescription里,方便代理方法调用
        let task = session.dataTask(with: request)
        task.taskDescription = "\(completion)"
        task.resume()
    }
    
    // 监听重定向事件,拿到跳转后的目标URL
    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
        if let finalURL = request.url {
            // 拿到目标URL后停止继续跳转
            completionHandler(nil)
            // 调用回调返回结果
            if let completion = task.taskDescription as? ((URL?) -> Void) {
                completion(finalURL)
            }
        } else {
            // 如果还有后续跳转,继续跟进
            completionHandler(request)
        }
    }
    
    // 请求完成的兜底处理(无重定向或出错时)
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error = error {
            print("短链接解析失败:\(error.localizedDescription)")
            if let completion = task.taskDescription as? ((URL?) -> Void) {
                completion(nil)
            }
            return
        }
        
        // 如果没有重定向,返回原URL
        if let responseURL = task.response?.url {
            if let completion = task.taskDescription as? ((URL?) -> Void) {
                completion(responseURL)
            }
        } else {
            if let completion = task.taskDescription as? ((URL?) -> Void) {
                completion(nil)
            }
        }
    }
}

// 使用示例
let resolver = ShortLinkResolver()
if let shortURL = URL(string: "https://j.map.baidu.com/YwUSO") {
    resolver.resolveBaiduShortLink(shortURL) { finalURL in
        guard let url = finalURL else {
            print("解析失败")
            return
        }
        print("拿到的完整URL:\(url)")
        // 这里可以处理你的业务逻辑,比如打开地图、存储URL等
    }
}

方案2:轻量HEAD请求获取Location头

如果不需要监听跳转过程,用HEAD请求只获取响应头会更高效,避免下载不必要的响应体:

import UIKit

func resolveBaiduShortLinkLightweight(_ shortURL: URL, completion: @escaping (URL?) -> Void) {
    var request = URLRequest(url: shortURL)
    request.httpMethod = "HEAD" // 仅请求响应头,更轻量
    // 同样需要设置浏览器UA
    request.setValue("Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", forHTTPHeaderField: "User-Agent")
    
    let task = URLSession.shared.dataTask(with: request) { _, response, error in
        DispatchQueue.main.async {
            if let error = error {
                print("请求出错:\(error.localizedDescription)")
                completion(nil)
                return
            }
            
            // 检查是否是3xx重定向响应
            guard let httpResponse = response as? HTTPURLResponse,
                  (300...399).contains(httpResponse.statusCode),
                  let locationString = httpResponse.allHeaderFields["Location"] as? String,
                  let finalURL = URL(string: locationString) else {
                // 无重定向或解析失败时返回原URL
                completion(shortURL)
                return
            }
            
            completion(finalURL)
        }
    }
    task.resume()
}

// 使用示例
if let shortURL = URL(string: "https://j.map.baidu.com/YwUSO") {
    resolveBaiduShortLinkLightweight(shortURL) { url in
        print("最终完整URL:\(url ?? shortURL)")
    }
}

关键注意事项

  • User-Agent必须设置:百度短链接服务会拦截非浏览器标识的请求,所以一定要模拟移动端浏览器的UA,否则可能返回403或者不触发跳转。
  • 处理多次重定向:如果遇到短链接嵌套跳转的情况,可以在方案1里循环跟进,或者在方案2里递归调用解析方法,直到拿到非3xx响应的URL。
  • 网络权限:确保你的App已经在Info.plist中配置了网络权限(NSAppTransportSecurity不需要额外配置,因为百度短链接是HTTPS协议)。
  • 错误处理:一定要处理网络异常、短链接无效、无跳转头等边缘情况,避免崩溃或逻辑异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:42:33