0

下面的代码在单击 tinyurl 链接时为我提供了 tinyurl 链接上的 NSLog 重定向位置。但是,如果我删除以下代码[[UIApplication sharedApplication] openURL:[request URL]];,它将给我 NSLog 中的实际网站,而不是 tinyurl 链接。在呈现共享应用程序代码的同时,我如何才能在 NSLog 中拥有实际的网站 URL?

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType  {
    NSLog(@"Redirect Location: %@",[request.URL absoluteString]);
    [[UIApplication sharedApplication] openURL:[request URL]];
}
4

1 回答 1

1

简短的回答:

使用UIWebViewDelegate方法shouldStartLoadWithRequest不是确定您将被重定向到哪个站点的好机制(特别是因为从您的代码判断,您最终将在外部应用程序中打开它,而不是您的UIWebView),因为您在shouldStartLoadWithRequest重定向之前得到发生。但是,您可以使用NSURLConnectionNSURLConnectionDataDelegate方法来确定您最终将被重定向到哪里。

长答案:

如果你看shouldStartLoadWithRequest,如果你返回YES,你会让UIWebView跟随重定向请求。考虑以下内容shouldStartLoadWithRequest

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"%@", request.URL);
    return YES;
}

如果您将其与随机bit.lyURL 一起使用,例如http://nyti.ms/Yi6EAk,您将看到以下日志:

2013-03-12 21:23:31.418 webtest[6959:c07] http://nyti.ms/Yi6EAk
2013-03-12 21:23:31.511 webtest[6959:c07] http://bit.ly/Yi6EAk?cc=0d7134b272b1004cb954d0400076e9fa
2013-03-12 21:23:31.560 webtest[6959:c07] http://www.nytimes.com/2013/03/13/us/politics/ryans-plan-aims-to-balance-budget-in- 10-years.html?hp&_r=0

第三次调用shouldStartLoadWithRequest是我定义bit.ly重定向 URL 的实际 URL,即两个连续重定向的最终目的地。但是,如果您shouldStartLoadWithRequest返回NO了,那么您将永远无法弄清楚它最终会被重定向到哪个站点。(顺便说一句,您shouldStartLoadWithRequest绝对应该返回YESNO......您的样品也不会返回。)

如您所见,因为shouldStartLoadWithRequest发生在重定向有机会发生之前,您会看到每个重定向都发生了。根据生成的站点的功能,您可能会shouldStartLoadWithRequest在页面检索额外内容时看到后续调用。这使得这是一种尴尬的机制,用于找出您最终被重定向到的站点。

如果您确实需要您被重定向到的站点,您可能想要使用NSURLConnection, 代替。虽然这通常用于从服务器实际检索数据,但它也可以用于捕获重定向(但不会受到UIWebViewDelegate方法问题的影响shouldStartLoadWithRequest,在这种情况下,很难区分真正的重定向和页面的随机附加内容)可随后要求)。

所以考虑以下几点:

self.url = [NSURL URLWithString:@"http://nyti.ms/Yi6EAk"];
NSURLRequest *request = [NSURLRequest requestWithURL:self.url];
[NSURLConnection connectionWithRequest:request delegate:self];

然后,您可以实现connection:willSendRequest:redirectResponse:一个NSURLConnectionDataDelegate方法,该方法将跟踪各种重定向:

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
    self.url = request.URL;

    return request;
}

显然,因为您NSURLConnection用于跟踪重定向,但我们并不真正关心responseData我们通常NSURLConnection用来检索的,所以我们可以在您收到良好响应后立即取消连接(确信我们已经知道哪个网站最终被重定向):

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [connection cancel];

    NSLog(@"Ok, we now know that the resulting URL is %@", self.url);
}

顺便说一句,您可能还想捕获连接错误,例如:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"Ok, we failed trying to retrieve data from %@", self.url);
}

最后,值得指出的是,这种发出 HTTP 请求NSURLConnection并让它跟随整个重定向系列的技术是一个非常低效的过程,因此您必须决定是否值得。但这是确定您的 HTTP 重定向将引导您到哪里的一种方法。

One final caveat, this captures traditional redirects, but if the page is doing any client-side JavaScript redirects, I don't think this technique will work. It works for the vast majority of redirected HTTP requests, though.

于 2013-03-13T01:55:54.650 回答