在WebKit中,如何获取资源的内容? [英] In WebKit, how do I get the content of a resource?

查看:107
本文介绍了在WebKit中,如何获取资源的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been writing a Mac app to inspect each HTTP request and so I'm using WebView to load the request.

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

The problem is that I can't seem to figure out how to get the content of each of the resource items.

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

I'm trying to get the content for the resource via the WebResourceLoadDelegate method:

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

这似乎不起作用.

我也在看[dataSource data],但这只是为我提供了请求的HTML,而不是资源项的数据.

I was also looking at [dataSource data] but that just gave me the HTML for the request and not the data for the resource item.

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

Any ideas on how I can get the content of the resource?

推荐答案

是的,这应该起作用,而且似乎很久以前就起作用了.您可以通过实现自定义NSURLProtocol来解决此问题.

Yes, that ought to work, and it appears that once upon a time it did. You can work around it by implementing a custom NSURLProtocol.

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

First, you'll need to figure out which requests you are interested in intercepting (or all of them, no matter). I do this in my WebResourceLoadDelegate. If I care about the request, I replace it with one of my own, attaching myself as a property. I'll use that property in the NSURLProtocol later.

- (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看起来像这样.

My NSURLProtocol looks like this.

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

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

In my NSURLProtocol subclass, I can use the attached property to see if I should intercept the response.

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

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

In initWithRequest, I move the delegate into my NSURLProtocol instance, and remove the property from the request. This prevents an infinite loop later, when I actually try to load this request.

- (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加载内容.

The rest is stock URL loading stuff.

- (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];
}

这篇关于在WebKit中,如何获取资源的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆