Остановить WebView от перехода на любые URL - PullRequest
1 голос
/ 09 декабря 2011

Я сделал простое приложение для Mac, однако, когда оно загружается в контент (через JS), оно перенаправляет из-за добавления или чего-то еще, есть ли способ предотвратить переход WebView на любой другой 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 ]

2 голосов
/ 09 декабря 2011

Подробнее connection:willSendRequest:redirectResponse:

см. здесь

ОБНОВЛЕНО: извините, я сразу почувствовал, что это приложение для Mac, а не приложение для iPhone. Ограниченный опыт работы с первым; Тем не менее, я считаю, что применимы одни и те же понятия, просто они созданы по-разному.

Глядя на документацию, похоже, что вы хотите webView:resource:willSendRequest:redirectResponse:fromDataSource (подробности см. здесь ). Вам также необходимо установить webberAppDelegate s resourceLoadDelegate на self.

ОБНОВЛЕНО: хорошо, вот немного подробнее о процессе. Вам нужно немного понять, как протоколы и делегаты работают в Objective-C. Прочитайте этот материал в поддержку следующего.

Протоколы функционируют как интерфейсы в Java или C # или абстрактные функции в C ++. Они в основном форма контракта. Они являются обязательными по умолчанию, но могут быть явно помечены как @optional, что означает, что компилятор не захлебнется, если он не указан. Если вы посмотрите документацию для WebResourceLoadDelegate, вы увидите, что все методы являются необязательными. Нам нужен только один метод webView:resource:willSendRequest:redirectResponse:fromDataSource.

Другая часть этого - концепция делегата. Делегаты функционируют как обратные вызовы. Это включает в себя как объект, который будет выполнять логику обратного вызова, так и реализацию логики (то есть реализацию метода из протокола, описанного выше). Это может быть реализовано несколькими способами, но у Какао есть более или менее стандартизированный способ сделать это. Вы должны предоставить реализацию метода, и вам нужно определить, какой объект будет выполнять логику. Обратите внимание, что WebView имеет несколько различных протоколов делегатов. Принятие всего или части одного из них называется , соответствующим протоколу. Это указано в коде как (я предоставляю скелет вашего класса здесь):

@interface webberAppDelegate : NSObject<WebResourceLoadDelegate> {
    WebView* webview;
}
@end

здесь я предполагаю, что вы произошли от NSObject; замените, какой бы ни был ваш базовый класс. Это позволяет компилятору ожидать, что вы предоставите реализации обязательных методов, а также любые дополнительные методы, которые вам требуются. Он будет жаловаться, если вы не реализуете обязательные методы.

Более важной задачей является установление того, что у ивара Webview есть делегат, который предоставит реализации для одного или всех методов, объявленных WebResourceLoadDelegate. У вас есть недвижимость для этого ивара - webview. Где-то (например, в viewDidLoad - это то, где я бы сделал это в iOS), вы должны объявить:

webview.resourceLoadDelegate = self;

при условии, что вы хотите обработать обратный вызов webberAppDelegate. Затем в реализации webberAppDelegate необходимо указать определение метода webView:resource:willSendRequest:redirectResponse:fromDataSource:

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

Если вы реализуете это много, вы должны увидеть оператор log, отображаемый в консоли при запуске приложения. Именно в этом методе вам нужно обрабатывать перенаправление. Как я уже говорил, я не очень разбираюсь в реализации этого протокола. Согласно этому потоку , это может быть протокол WebPolicyDelegate, который вы хотите. Вовлеченные принципы будут такими же.

0 голосов
/ 17 ноября 2015

Хотя ответ jstevenco объясняет, как вы можете узнать, пытается ли веб-просмотр перейти на другой URL-адрес, он не дает ответа на вопрос, как можно предотвратить переход веб-просмотра на такой URL-адрес.

Если вы хотите запретить WebView переходить по любому другому URL-адресу, вы должны реализовать Протокол WebPolicyDelegate . Важно отметить, что это неофициальный протокол, поэтому вы не можете написать @interface MyDelegate : NSObject <WebPolicyDelegate>.

Вместо этого в вашем webberAppDelegate.h импортируемом Webkit:

#import <WebKit/WebPolicyDelegate.h>

и в webberAppDelegate.m реализует метод webView:decidePolicyForNavigationAction:request:frame:decisionListener:, этот метод "вызывается каждый раз, когда происходит перенаправление на сервер, если оно не заблокировано более ранним решением политики" . ( Документация по протоколу WebPolicyDelegate )

В этом методе вы должны сообщить решению SolutionListener, что оно должно игнорировать любое перенаправление. Это реализация:

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

  }
0 голосов
/ 16 декабря 2011

Насколько я могу сказать, эти два метода делегата могут перехватывать 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);    
}

привет Jimmy

0 голосов
/ 09 декабря 2011

Да, вы можете сделать это. Реализация

– webView:shouldStartLoadWithRequest:navigationType:

Это делегат . Этот метод вызывается всякий раз, когда ваше веб-представление собирается сделать запрос. Так что теперь, когда кто-то нажимает кнопку на вашей веб-странице, вы получите вызов этого метода. После того, как вы поймаете этот вызов, вы можете делать с ним все, что захотите. Например, перенаправить ссылку через ваши собственные серверы или зарегистрировать запрос к вашему серверу об активности пользователя и т. Д.

Пример - здесь вы пытаетесь перехватить любые ссылки, нажимаемые на вашей веб-странице, и сначала пройти через 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;
}

Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...