【问题标题】:In WebKit, how do I get the content of a resource?在 WebKit 中,我如何获取资源的内容?
【发布时间】:2011-03-10 11:32:19
【问题描述】:

我一直在编写一个 Mac 应用程序来检查每个 HTTP 请求,因此我使用 WebView 来加载请求。

问题是我似乎无法弄清楚如何获取每个资源项的内容。

我正在尝试通过WebResourceLoadDelegate 方法获取资源的内容:

- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource

这似乎不起作用。

我也在查看[dataSource data],但这只是给了我请求的 HTML,而不是资源项的数据。

关于如何获取资源内容的任何想法?

【问题讨论】:

  • 您找到解决方案了吗?我正在寻找类似的功能。
  • 我正在考虑做 webArchive 然后尝试阅读资源,但似乎我仍然有这个问题。另一个解决方案是从 URL 下载资源,但我决定不这样做,并将我的项目放在积压日志中。 (github.com/fernyb/HttpSafari)

标签: objective-c webkit webview


【解决方案1】:

在那个委托方法中使用这个

  for(NSString *s in [dataSource subresources])
        NSLog(@"resource : %@",s);

它将显示WebDataSource中正在下载的所有资源

【讨论】:

    【解决方案2】:

    是的,这应该有效,而且似乎从前确实有效。你可以通过实现一个自定义的 NSURLProtocol 来解决它。

    首先,您需要确定您有兴趣拦截哪些请求(或所有请求,无论如何)。我在我的 WebResourceLoadDelegate 中执行此操作。如果我关心请求,我会用我自己的请求替换它,将自己作为财产。稍后我将在 NSURLProtocol 中使用该属性。

    - (NSURLRequest*) webView:(WebView*)sender 
                     resource:(id)identifier 
              willSendRequest:(NSURLRequest*)request 
             redirectResponse:(NSURLResponse*)redirectResponse     
               fromDataSource:(WebDataSource*)dataSource
    {
        // Am I interested in this request?
        if (/* figure out if you want it or not */) {
            NSMutableURLRequest* newRequest = [[request mutableCopy] autorelease];
            [NSURLProtocol setProperty:self forKey:@"MyApp" inRequest:newRequest];
            return newRequest;
        }
        else {  
            // Not interested, let it go through normally
            return request;
        }
    }
    

    我的 NSURLProtocol 看起来像这样。

    @interface MyURLProtocol : NSURLProtocol {
        id _delegate;
        NSURLConnection* _connection;
        NSMutableData* _data;
    }
    @end
    

    在我的 NSURLProtocol 子类中,我可以使用附加的属性来查看是否应该拦截响应。

    + (BOOL) canInitWithRequest:(NSURLRequest*)request
    {   
        id delegate = [NSURLProtocol propertyForKey:@"MyApp" inRequest:request];
        return (delegate != nil);
    }
    

    在 initWithRequest 中,我将委托移动到我的 NSURLProtocol 实例中,并从请求中删除该属性。这可以防止以后在我实际尝试加载此请求时出现无限循环。

    - (id) initWithRequest:(NSURLRequest*)theRequest 
            cachedResponse:(NSCachedURLResponse*)cachedResponse 
                    client:(id<NSURLProtocolClient>)client
    {
        // Move the delegate from the request to this instance
        NSMutableURLRequest* req = (NSMutableURLRequest*)theRequest;    
        _delegate = [NSURLProtocol propertyForKey:@"MyApp" inRequest:req];  
        [NSURLProtocol removePropertyForKey:@"MyApp" inRequest:req];
    
        // Complete my setup
        self = [super initWithRequest:req cachedResponse:cachedResponse client:client];
        if (self) {
            _data = [[NSMutableData data] retain];
        }
        return self;
    }
    

    剩下的是股票 URL 加载的东西。

    - (void) startLoading
    {
        _connection = [[NSURLConnection connectionWithRequest:[self request] delegate:self] retain];
    }
    
    - (void) stopLoading
    {
        [_connection cancel];
    }
    
    - (void)connection:(NSURLConnection*)conn didReceiveResponse:(NSURLResponse*)response 
    {
        [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:[[self request] cachePolicy]];
        [_data setLength:0];
    }
    
    - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
    {
        [[self client] URLProtocol:self didLoadData:data];
        [_data appendData:data];
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection*)conn
    {
        [[self client] URLProtocolDidFinishLoading:self];
    
        // Forward the response to your delegate however you like
        if (_delegate && [_delegate respondsToSelector:@selector(...)]) {
            [_delegate ... withRequest:[self request] withData:_data];
        }
    }
    
    - (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)theRequest redirectResponse:(NSURLResponse*)redirectResponse
    {
        return theRequest;
    }
    
    - (void)connection:(NSURLConnection*)conn didFailWithError:(NSError*)error 
    {
        [[self client] URLProtocol:self didFailWithError:error];
    }
    

    【讨论】:

    • 确保您在其中某处执行[NSURLProtocol registerClass:[MyURLProtocol class]],否则这将不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 2012-12-01
    • 2011-05-22
    • 2020-10-01
    • 1970-01-01
    相关资源
    最近更新 更多