在嵌入的UIWebView中指定HTTP referer

13

在我的应用程序中,我允许用户在嵌入的UIWebView中打开外部页面。我是否可以设置发送该请求的引用者标头?当用户打开这些外部页面时,我希望我的应用程序能够获得“cred”。

2个回答

20

使用- setValue:forHTTPHeaderField:设置referer

NSMutableURLRequest* request = ...;
[request setValue:@"https://myapp.com" forHTTPHeaderField: @"Referer"];

但是请注意,根据HTTP RFC的规定,您不应该这样做,因为您的应用程序不能使用URI进行寻址:

如果请求URI来自没有自己的URI的来源(例如用户键盘输入),则不得发送Referer字段。

...除非您正在使用绑定到您的应用程序的自定义协议(myapp://blah.com/blah)。

您可以创建一个并手动调用loadRequest:或拦截用户发出的常规请求。

- (BOOL) webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType) navigationType 
{
    NSDictionary *headers = [request allHTTPHeaderFields];
    BOOL hasReferer = [headers objectForKey:@"Referer"]!=nil;
    if (hasReferer) {
        // .. is this my referer?
        return YES;
    } else {
        // relaunch with a modified request
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                NSURL *url = [request URL];
                NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
                [request setHTTPMethod:@"GET"];
                [request setValue:@"https://whatever.com" forHTTPHeaderField: @"Referer"];
                [self.webView loadRequest:request];
            });
        });
        return NO;
    }
}

我不知道那是否合适,但你可以拦截并重新发起请求。 - Jano
谢谢您的回答。我已经更新了问题,只询问如何在UIWebView中发送标头,并将接受您的答案。我会开一个新问题来询问如何在移动Safari中发送标头。 - Edward Dale
3
事实证明,我可以可靠地将来自 UIWebViewDelegate 的请求转换为 NSMutableURLRequest。上面建议的请求更换解决方案会破坏页面中的 iframe,并通过在完整浏览器中重新打开它们来修复它们。 - Edward Dale
@scompt.com,你的建议对我不起作用。你能提供一些代码行吗? - Wédney Yuri
@scompt.com 看起来并不是所有的请求实际上都是NSMutableURLRequests(我还没有找到一个模式),所以强制转换并不可靠。 - thomers
显示剩余2条评论

0

我自己没有使用过这个,但是看起来NSURLProtocol是拦截和修改URL请求的官方方式。这里有一个教程:http://www.raywenderlich.com/59982/nsurlprotocol-tutorial

我正在使用您的解决方案,将请求转换为NSMutableURLRequest,但由于没有文档说明这是可变请求,所以存在一些风险,即Apple可能会在未来使用不可变对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接