- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
目前我正在开发一个混合应用程序,它使用 webView shouldStartLoadWithRequest: 为登录提供 token 。我的功能适用于我发出的每个正常请求(例如单击)
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
NSLog([NSString stringWithFormat:@"Loading View: %@",[[request URL] absoluteString]]);
if ([[[request URL] absoluteString] rangeOfString:BASE_URL].location != NSNotFound) {
NSString *token = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginToken];
NSString *hash = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginHash];
NSString *params = [NSString stringWithFormat:@"mobile=app&user_token=%@&user_hash=%@",token,hash];
if([[request URL] query] == nil) {
[self LoadUrl:[[request URL] absoluteString] withGetParams:params append:NO];
return NO;
}else{
if([[[request URL] absoluteString] rangeOfString:params].location == NSNotFound){
[self LoadUrl:[[request URL] absoluteString] withGetParams:params append:YES];
return NO;
}
}
}
-(void)LoadUrl:(NSString *)url withGetParams:(NSString *)params append:(BOOL)append{
NSString *PreUrl;
if(append == YES) PreUrl = [NSString stringWithFormat:@"%@&%@",url,params];
else PreUrl = [NSString stringWithFormat:@"%@?%@",url,params];
NSURL *nsurl = [NSURL URLWithString: PreUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:nsurl];
[self.WebView loadRequest:request];
}
我对这段代码的问题是,如果我加载一个图像,例如它将被检测为“要进行哈希附加”(这是正确的,我希望每个请求都包含 Auth)但是图像将加载到 Webview 本身中。
我的第一次尝试(在我切换到这个模型之前)是修改解析的请求。但是每个更改都被忽略了....
有谁知道我该如何解决这个问题?有没有办法真正修改请求?或者,如果不是,我是否可以至少确定请求的“目标”或转发它?
感谢您的帮助
最佳答案
我找到了解决问题的方法。 Sublcassing 是正确的方法,但不是 UIWebView,而是一个自己的 NSURLProtocol。
所以我做了什么:
创建自己的 NSURLProtocol 子类
@interface MyURL : NSURLProtocol <NSURLConnectionDelegate>
为 HTTP 连接添加一些标准处理
@interface MyURL () <NSURLConnectionDelegate>
@property (nonatomic, strong) NSURLConnection *connection;
@property (nonatomic, strong) NSMutableData *mutableData;
@property (nonatomic, strong) NSURLResponse *response;
@end
@implementation MyURL
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
- (void)stopLoading
{
[self.connection cancel];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.client URLProtocol:self didLoadData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self.client URLProtocol:self didFailWithError:error];
self.connection = nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self.client URLProtocolDidFinishLoading:self];
self.connection = nil;
}
@end
现在是有趣的部分 - 修改发送到我的服务器的每个请求
所以首先:检查这个请求是否到达我的服务器并确定我的协议(protocol)是否应该处理它
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSString *token = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginToken];
NSString *hash = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginHash];
if([NSURLProtocol propertyForKey:@"TokenSet" inRequest:request]) return NO; // We already handled it
if((hash == nil) || (token == nil) ) return NO; // We are not logged in
NSString *params = [NSString stringWithFormat:@"mobile=app&user_token=%@&user_hash=%@",token,hash];
if (([[[request URL] absoluteString] rangeOfString:BASE_URL].location != NSNotFound) && ([[[request URL] absoluteString] rangeOfString:@"/assets/"].location == NSNotFound)){
if([[[request URL] absoluteString] rangeOfString:params].location == NSNotFound){
return YES; // URL does not contain the login token & we're not requesting an asset (js/img/etc.)
}
}
return NO;
}
所以如果 + (BOOL)canInitWithRequest:(NSURLRequest *)request 返回 yes,我必须处理该请求。我已经知道它不包含登录 token 和哈希,所以我必须确定是否必须附加它。为了修改一般的请求,我创建了我们请求的 MutableCopy,修改它并将我们的 URLConnection 设置为请求。
- (void)startLoading
{
NSMutableURLRequest *newRequest = [self.request mutableCopy];
NSString *PreURL;
NSString *token = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginToken];
NSString *hash = [[NSUserDefaults standardUserDefaults] stringForKey:kDefaultsKeyLoginHash];
NSString *params = [NSString stringWithFormat:@"mobile=app&user_token=%@&user_hash=%@",token,hash];
if([[newRequest URL] query] == nil) {
PreURL = [NSString stringWithFormat:@"%@?%@",[[newRequest URL] absoluteString],params];
}else{
if([[[newRequest URL] absoluteString] rangeOfString:params].location == NSNotFound){
PreURL = [NSString stringWithFormat:@"%@&%@",[[newRequest URL] absoluteString],params];
}
}
NSURL *nsurl = [NSURL URLWithString: PreURL];
[newRequest setURL:nsurl];
[NSURLProtocol setProperty:@"YES" forKey:@"TokenSet" inRequest:newRequest];
self.connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
}
为了完成这一切,我们将我们的 URL 协议(protocol)注册为 AppDelegate 中的协议(protocol)。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[NSURLProtocol registerClass:[MyURL class]];
}
有了这个解决方案,我首先拥有的优势是在我的应用程序的任何部分发送到我的服务器的任何请求中都有我的登录 token 。不用再担心这个了。而且我可以做一些很酷的事情,比如在第一次加载资源后节省资源,甚至可以在 Webviews 中使用我的 App-Bundle 中的图像......
我希望这对某人有所帮助。
关于ios - 修改webView的Request shouldStartLoadWithRequest :,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23264338/
我正在尝试调用 shouldStartLoadWithRequest 但它没有被调用,我用谷歌搜索它并发现我必须将 delegte 设置为 uiwebview 我正在使用标签栏项目 我已经添加了 @i
目前我正在开发一个混合应用程序,它使用 webView shouldStartLoadWithRequest: 为登录提供 token 。我的功能适用于我发出的每个正常请求(例如单击) - (BOO
我有一个 View 控制的应用程序。在我的 xib 上,我没有 webview,但我确实有按钮可以调出具有 webview 的类。所以点击第一个按钮,会弹出一个 uiwebview,依此类推。 现在,
我研究了又研究,但仍然不明白为什么 shouldStartLoadWithRequest 从未被调用过。我的页面加载正常,一些 UIWebview 委托(delegate)协议(protocol)方法
我的应用程序的一部分是用 JS 编写的,并在 WebView 中运行。我正在使用 UIWebView shouldStartLoadWithRequest 方法来捕获 http 请求,作为 JS 和
我最近更新到 cordova 6.0。在我的 MainViewController 代码中,我实现了 shouldStartLoadWithRequest UIWebViewDelegate 方法来做
在我的 UIWebView 中,我正在加载 Twitter 页面。我想将 webView 内的所有点击都作为单独的页面打开。所以我实现了 shouldStartLoadWithRequest: -(B
我收到了 HTML 格式的描述文本,我正在将它加载到 Web View 中,如果在描述中单击了一个链接,那么我将它加载到单独的 View Controller 中。但是 shouldStartLoad
我用这段代码初始化 WebView: self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; self.webView.d
在我的 iPhone 应用程序中,我有一个 UIWebView,我正在其中加载本地 html。一切正常,但现在我希望能够处理本地链接(到脚注):当我点击本地链接时,我希望能够跳转到它引用的脚注,然后能
我已经构建了一个 Cordova 应用程序,我只是在 xcode 中添加一些 native 功能。我想从我的应用程序中拦截 url,如下所示: How to invoke Objective C me
我在我的一个程序中非常成功地使用了 shouldStartLoadWithRequest,但是整个项目只是概念验证而且很邋遢,我正在重新开始一个新项目。 然而 shouldStartLoadWithR
总的来说,我是编码新手!我正在尝试创建一个不允许导航到查看器的 webview。我已经输入了大部分编码,但我有两个未声明的错误,我不确定如何解决这个问题。 我想做的是创建一个 webView,但我想在
我在我的应用程序中使用 UIWebView 并且我正在覆盖 shouldStartLoadWithRequest 消息以检测正在单击哪种链接。如果它是一个“特殊”链接,我将 UIViewControl
我的应用程序中嵌入了一个 UIWebView。我正在做的是,为从它发出的所有请求添加一个 header (具体来说,授权 header )。 当从 HTML iframe 打开 URL 但它似乎无法向
我有一个带有 UIWebView Controller 的 View Controller 。我试图在 web View 的 html 内容中获取 javascript,以将一些信息传递给我的 obj
我已经开始使用 shouldStartLoadWithRequest 并在我理解的情况下遇到了令人费解的行为。我以最简单的形式尝试了以下... - (BOOL)webView:(UIWebView *
我正在使用 webStoryViewController,它使用 UIWebView 来处理网页。当用户单击 Web 链接时,它会从其他屏幕模态调用。如果找到应用商店链接,那么我有一个代码可以关闭我的
我正在创建一个具有 WebView 的应用程序。当用户单击 Web View 中的链接或按钮时,我希望能够获取新的 url 并编辑新的 url。 shouldStartLoadWithRequest
我有一个 UIWebView带有 delegate 的对象设置 webView.delegate = self和UIView 在所有 iOS 设备中都会调用以下委托(delegate)调用,除了搭载
我是一名优秀的程序员,十分优秀!