使用UiWebView中的本地Javascript文件覆盖远程HTML?

时间:2014-07-04 15:53:36

标签: javascript html ios css uiwebview

我们正在构建移动应用程序。虽然我们不是客观的程序员,但我们是网络开发人员,并且有一个想法,即使用HTML / CSS构建类似本机的应用程序。

我们计划通过UIWebView从我们的服务器加载外部空白HTML文件(由Drupal提供),并希望从本地设备加载CSS和Javascript。即网站发送裸骨非风格的HTML,应用程序加载本地CSS和JS来设置它的样式。

更新#3 - 已找到解决方案,但存在轻微错误:

我们首先对远程URL进行了正常的NSURL调用。并在- (void)viewDidLoad

中将webview委托设置为self
NSURL *url = [NSURL URLWithString:@"localhost:8888/ios/"];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
mainView.delegate = self;
[mainView loadRequest:requestURL];

然后在- (void)webViewDidFinishLoad:(UIWebView *)webView中我们创建了一个新的NSSstring,它调用了一个JS DOM来将.jS文件注入到标题中。

NSString * JScode =
@"var script = document.createElement('script');"
"script.type = 'text/javascript';"
"script.src = 'file';"
"document.getElementsByTagName('head')[0].appendChild(script);"
;

由于我们计划在应用程序本地托管Javascript和CSS,因此我们决定调用一个可以加载css和JS组件的.jS文件。

为了让我们调用实际的.js文件,我们必须对实际文件路径执行字符串替换:

JScode = [JScode stringByReplacingOccurrencesOfString:@"file" withString: [[NSBundle mainBundle] pathForResource:@"script" ofType:@"js" inDirectory:@"www"]];

然后在最后我们运行了一个stringByEvaluatingJavaScriptFromString:JScode并加载了.js文件!

之前:

Before

After

重播问题: 无论出于何种原因,代码显示文件已加载但有一个奇怪的URL,当我们点击时给我们一个文件未找到错误。在模拟器之外,JS代码正确执行。

帮助?

2 个答案:

答案 0 :(得分:1)

我看到至少2个选项:

  • 您可以尝试使用file:个网址。问题在于它们必须是绝对的,并且安装路径是可变的,因此您可能必须将其发送到服务器,以便他可以返回包含正确URL的HTML。

  • 您可以手动加载HTML,然后修改它以添加指向本地资源的链接,并使用loadHTMLString:baseURL:显示它。但是,您需要拦截所有进一步的加载请求(链接点击后)在webView:shouldStartLoadWithRequest:navigationType:中。那个方法应该做同样的事情(加载HTML,修改它,显示它)。

编辑:第二个选项的部分代码:

- (void)loadView
{
    [super loadView];
    self.view = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"url-from-server"]];

    receivedData = [NSMutableData dataWithCapacity: 0];

    // create the connection with the request
    // and start loading the data
    connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (!connection) {
        // Release the receivedData object.
        receivedData = nil;

        // Inform the user that the connection failed.
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // This method is called when the server has determined that it
    // has enough information to create the NSURLResponse object.

    // It can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.

    // receivedData is an instance variable declared elsewhere.
    [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // Append the new data to receivedData.
    // receivedData is an instance variable declared elsewhere.
    [receivedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
    // do something with the data
    // receivedData is declared as a property elsewhere
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);

    NSString *string = [[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"REPLACEME" withString:[[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"css"]] absoluteString]];

    [((UIWebView *)self.view) loadHTMLString:string baseURL:[NSURL URLWithString:@""]];

    // Release the connection and the data object
    // by setting the properties (declared elsewhere)
    // to nil.  Note that a real-world app usually
    // requires the delegate to manage more than one
    // connection at a time, so these lines would
    // typically be replaced by code to iterate through
    // whatever data structures you are using.
    connection = nil;
    receivedData = nil;
}

HTML文件如下所示:

<html>
        <head>
                <link rel="stylesheet" href="REPLACEME" type="text/css">
        </head>
        <body>
                whatever
        </body>
</html>

CSS称为test.css

答案 1 :(得分:0)

我们找到了解决方案。而不是尝试注入本地文件,我们遇到了this solution,其中应用程序扫描网站以进行远程参考,例如“url.com/style.css”并将其替换为本地文件。