studio example evaluatejavascript android android-webview webviewclient

android - example - Interceptar y anular las solicitudes HTTP de WebView



webview evaluatejavascript (7)

Aquí está mi solución que uso para mi aplicación.

Tengo varias carpetas de activos con archivos de fuentes css / js / img anf.

La aplicación obtiene todos los nombres de archivo y busca si se solicita un archivo con este nombre. En caso afirmativo, lo carga desde la carpeta de activos.

//get list of files of specific asset folder private ArrayList listAssetFiles(String path) { List myArrayList = new ArrayList(); String [] list; try { list = getAssets().list(path); for(String f1 : list){ myArrayList.add(f1); } } catch (IOException e) { e.printStackTrace(); } return (ArrayList) myArrayList; } //get mime type by url public String getMimeType(String url) { String type = null; String extension = MimeTypeMap.getFileExtensionFromUrl(url); if (extension != null) { if (extension.equals("js")) { return "text/javascript"; } else if (extension.equals("woff")) { return "application/font-woff"; } else if (extension.equals("woff2")) { return "application/font-woff2"; } else if (extension.equals("ttf")) { return "application/x-font-ttf"; } else if (extension.equals("eot")) { return "application/vnd.ms-fontobject"; } else if (extension.equals("svg")) { return "image/svg+xml"; } type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); } return type; } //return webresourceresponse public WebResourceResponse loadFilesFromAssetFolder (String folder, String url) { List myArrayList = listAssetFiles(folder); for (Object str : myArrayList) { if (url.contains((CharSequence) str)) { try { Log.i(TAG2, "File:" + str); Log.i(TAG2, "MIME:" + getMimeType(url)); return new WebResourceResponse(getMimeType(url), "UTF-8", getAssets().open(String.valueOf(folder+"/" + str))); } catch (IOException e) { e.printStackTrace(); } } } return null; } //@TargetApi(Build.VERSION_CODES.LOLLIPOP) @SuppressLint("NewApi") @Override public WebResourceResponse shouldInterceptRequest(final WebView view, String url) { //Log.i(TAG2, "SHOULD OVERRIDE INIT"); //String url = webResourceRequest.getUrl().toString(); String extension = MimeTypeMap.getFileExtensionFromUrl(url); //I have some folders for files with the same extension if (extension.equals("css") || extension.equals("js") || extension.equals("img")) { return loadFilesFromAssetFolder(extension, url); } //more possible extensions for font folder if (extension.equals("woff") || extension.equals("woff2") || extension.equals("ttf") || extension.equals("svg") || extension.equals("eot")) { return loadFilesFromAssetFolder("font", url); } return null; }

Tengo una WebView en mi aplicación en la que se abre un sitio (siempre igual, es mi propia página). El sitio tiene un código JS que carga algunas imágenes desde el host remoto.

Quiero interceptar solicitudes a tales imágenes (por patrón de URL) y devolver mi propio contenido (es decir, otra imagen), o dejar la solicitud intacta dependiendo de la lógica interna de la aplicación.

¿Es posible hacer eso?

EDITAR : El estado actual de la pregunta ...

WebView tiene la capacidad de establecer un WebViewClient (como lo señala Axarydax). WebViewClient tiene dos métodos útiles

  • shouldOverrideUrlLoading
  • onLoadResource

shouldOverrideUrlLoading puede interceptar cualquier carga de url, si la carga se desencadena por la interacción de la página (es decir, se hace clic en el enlace de una página, WebView.loadURL ("") no activa este método). También puede cancelar la carga de URL al devolver falso. Este enfoque no es utilizable, porque ''no es capaz de interceptar la carga de los recursos de la página (y las imágenes, lo que necesito interceptar, es un recurso de esa página).

onLoadResource se activa cada vez que se carga el recurso de la página (y las imágenes! thx a jessyjones), pero no hay forma de cancelarlo. Eso hace que este método no sea adecuado para mi tarea también.


Esto puede ayudar:

@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { String url = request.getUrl().toString(); WebResourceResponse response = super.shouldInterceptRequest(view, request); // load native js if (url != null && url.contains(INJECTION_TOKEN/* scheme define */)) { response = new WebResourceResponse( "text/javascript", "utf-8", loadJsInputStream(url, JsCache.getJsFilePath(path) /* InputStream */)); } return response; }




Por lo que sé, shouldOverrideUrlLoading no se llama para imágenes sino para hipervínculos ... Creo que el método apropiado es

@Override public void onLoadResource(WebView view, String url)

Este método se utiliza para cada recurso (imagen, hoja de estilo, secuencia de comandos) que carga la vista web, pero dado que es un vacío, no he encontrado una forma de cambiar esa url y reemplazarla para que cargue un recurso local ...


Prueba esto, lo he usado en una aplicación personal tipo wiki:

webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("foo://")) { // magic return true; } return false; } });


Una solución definitiva sería incorporar un servidor http simple escuchando en su puerto ''secreto'' en loopback. Luego puede sustituir la URL src de la imagen coincidente con algo como http://localhost:123/.../mypic.jpg