阻止WebView访问任何URL

时间:2011-12-09 16:36:33

标签: objective-c xcode macos uiwebview

我已经为mac创建了一个简单的应用程序,但是当它在内容(通过JS)中进行重新定位时,由于添加或其他内容,是否有任何方法可以防止WebView转到除了在其中定义的URL之外的任何其他URL码?

目前正试图用(更新)

来阻止它

webberAppDelegate.h

#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
@interface webberAppDelegate : NSObject <NSApplicationDelegate> {
    WebView *webview;
}

@property (assign)IBOutlet WebView *webview;

@end

webberAppDelegate.m

#import "webberAppDelegate.h"

@implementation webberAppDelegate

//@synthesize window;
//@synthesize webber;
@synthesize webview;

- (void)applicationDidFinishLaunching:(NSNotification *)Notification 
{
    NSURL*url=[NSURL URLWithString:@"http://simplyshows.com/dev/forums/"];
    NSURLRequest*request=[NSURLRequest requestWithURL:url];
    [[webview mainFrame] loadRequest:request];
    webview.resourceLoadDelegate = self;

}

-(NSURLRequest*) webView:(WebView*)webview resource:(id)sender willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectresponse fromDataSource:(WebDataSource*)dataSource {
    NSLog(@"willSendRequest delegate method called");
}

@end

4 个答案:

答案 0 :(得分:2)

有关connection:willSendRequest:redirectResponse:

的详细信息,请参阅here

更新:对不起,我对这是Mac应用程序而不是iPhone应用程序的事实轻描淡写。对前者的经验有限;但是,我认为相同的概念适用,只是实例化不同。

查看文档,看起来您需要webView:resource:willSendRequest:redirectResponse:fromDataSource(有关详细信息,请参阅here)。您还需要将webberAppDelegate的{​​{1}}设置为resourceLoadDelegate

更新:好的,这里有关于这个过程的更多细节。您需要了解一下protocolsdelegates在Objective-C中的工作原理。阅读该材料以支持以下内容。

Protocols的功能类似于Java或C#中的接口,或C ++中的抽象函数。它们基本上是一种合同形式。它们在默认情况下是强制性的,但可以显式标记为@optional,这意味着如果省略一个编译器,编译器不会阻塞。如果查看self的文档,您会发现所有方法都是可选的。我们只需要一个WebResourceLoadDelegate方法。

另一部分是代表的概念。代表充当回调。这涉及将执行回调逻辑的对象和逻辑的实现(即,来自上述协议的方法的实现)。这可以通过多种方式实现,但Cocoa有一种或多或少的标准化方式。您需要提供方法的实现,并且需要确定要执行逻辑的对象。请注意,webView:resource:willSendRequest:redirectResponse:fromDataSource有许多不同的委托协议。采用其中一个或全部的一部分称为符合协议。这在代码中说明(我在这里提供你班级的骨架):

WebView

这里我假设你派生于@interface webberAppDelegate : NSObject<WebResourceLoadDelegate> { WebView* webview; } @end ;替换你的基类是什么。这使编译器知道您将提供必需方法的实现以及您需要的任何可选方法。如果你没有实施强制性方法,它会抱怨。

更关键的一点是确定NSObject ivar有一个委托,它将为Webview声明的一个或所有方法提供实现。您拥有此ivar的财产 - WebResourceLoadDelegate。某处(例如,在viewDidLoad中 - 我在iOS中这样做)你需要声明:

webview

假设您希望webview.resourceLoadDelegate = self; 处理回调。然后在webberAppDelegate的实现中,您需要提供方法webberAppDelegate的定义:

webView:resource:willSendRequest:redirectResponse:fromDataSource

如果实现这一点,您应该在运行应用程序时看到在控制台中回显的日志语句。在那种方法中,您需要处理重定向。正如我之前所说,我不太熟悉这个协议的实现。根据{{​​3}}线程,它实际上可能是您想要的-(NSURLRequest*) webView:(WebView*)webview resource:(id)sender willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectresponse fromDataSource:(WebDataSource*)dataSource { NSLog(@"willSendRequest delegate method called"); } 协议。所涉及的原则是相同的。

答案 1 :(得分:0)

据我所知,这两个委托方法可以捕获其他帧/内容的URL。您应该尝试在页面上测试它们。阅读这些方法的帮助,了解如何例如阻止客户端重定向。

// WebView delegate methods

// Used to indicate that we've started loading (so that we can update our progress indicator
// and status text field)
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
{
    if( frame == [myWebView mainFrame] )
        NSLog(@"EntryController: Started loading mainFrame");
    else
        NSLog(@"EntryController: Started loading Frame : %@", [[frame.dataSource request] URL]); 
}


- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL
          delay:(NSTimeInterval)seconds fireDate:(NSDate *)date
          forFrame:(WebFrame *)frame
{
    NSLog(@"EntryController: willPerformClientRedirectToURL: %@",URL);    
}

问候 麦

答案 2 :(得分:0)

虽然jstevenco的回答解释了如何知道webview是否试图转到另一个网址,但它没有回答你如何阻止webview转到这样的网址。

如果要阻止WebView转到任何其他URL,则必须实现WebPolicyDelegate Protocol。重要的是要注意这是一个非正式的协议,所以你不能写@interface MyDelegate : NSObject <WebPolicyDelegate>

而是在webberAppDelegate.h导入Webkit:

#import <WebKit/WebPolicyDelegate.h>

并且在webberAppDelegate.m中实现方法webView:decidePolicyForNavigationAction:request:frame:decisionListener:,每次遇到服务器重定向时都会调用此方法“,除非被先前的策略决策”阻止。 (WebPolicyDelegate Protocol Documentation

在此方法中,您需要告诉decisionListener它必须忽略任何重定向。这是实施:

 - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation
         request:(NSURLRequest *)request
           frame:(WebFrame *)frame
decisionListener:(id <WebPolicyDecisionListener>)listener { 

        [listener ignore];

     }

但是,请注意此实现,因为您将忽略任何重定向,我不认为这是您想要的(它将是一个静态网页);更有可能的是,你想要的是防止离开你的域的重定向,这可能是你真正想要的:

 - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation
         request:(NSURLRequest *)request
           frame:(WebFrame *)frame
decisionListener:(id <WebPolicyDecisionListener>)listener { 


    if (![[[request URL] absoluteString] hasPrefix:@"yourdomain.com"]) {

        [listener ignore];
    }

  }

答案 3 :(得分:-1)

是的,你可以这样做。实施

– webView:shouldStartLoadWithRequest:navigationType:

delegate。只要您的webview即将发出请求,就会调用此方法。因此,当有人点击您网页上的按钮时,您将收到此方法的调用。在您接听此电话后,您可以选择随意使用它。比如通过您自己的服务器重定向链接,或者向服务器记录有关用户活动等的请求。

示例 - 在这里,您试图拦截点击您网页上的所有链接。首先通过myMethodAction传递。

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{ 
    if(navigationType == UIWebViewNavigationTypeLinkClicked)
    {
         if(overrideLinksSwitch.on == TRUE)
         {
             [self myMethodAction];
             [myWebView stopLoading];
             return YES;
         }
        else
        {
            return YES;
        }
    }
    return YES;
}

希望这会有所帮助......