Android:拦截来自WebView的 AJAX 调用

kuhbmx9i  于 2023-04-10  发布在  Android
关注(0)|答案(4)|浏览(270)

我想要一个HTML/javascript应用程序,在WebView中运行,以进行由Java代码处理的AJAX调用。
理想的做法是拦截调用(简单,只需使用shouldOverrideUrlLoading())并“返回”一些数据。
然而,除了使用loadUrl()调用javascript函数之外,我没有找到一种方法来“返回”对WebView的响应。
这对我不起作用,因为HTML/javascript应用程序是一个我无法控制的下拉式应用程序。就HTML/javascript应用程序而言,它只是执行AJAX调用并接收一些数据。
对此有什么想法吗?

shyt4zoc

shyt4zoc1#

好消息大家:在API级别11中,他们将shouldInterceptRequest方法放入WebViewClient类中。它也会在WebView触发器内的应用程序请求时触发。您可以如下所示覆盖它:

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
{
    if (magicallyMatch(url))
        return new WebResourceResponse("application/json", "utf-8", magicallyGetSomeInputStream());

    return null;
}

Android参考:
public WebResourceResponseshouldInterceptRequest(WebView view,String url)
自:API 11级
通知宿主应用程序有资源请求,并允许应用程序返回数据。如果返回值为null,则WebView将照常加载资源。否则,将使用返回的响应和数据。注意:此方法由网络线程调用,因此客户端在访问私有数据时应谨慎。

参数

view请求资源的WebView
url资源的原始URL。

返回

包含响应信息的WebResourceResponse,如果WebView应自行加载资源,则为null。
也检查WebResourceResponse
希望这能帮上忙。

nkoocmlb

nkoocmlb2#

您可以使用JavascriptInterface拦截 AJAX 调用沿着JQuery方法ajaxStartajaxComplete,方法如下:

// our JavascriptInterface
public class AjaxHandler {

    private static final String TAG = "AjaxHandler";
    private final Context context;

    public AjaxHandler(Context context) {
        this.context = context;
    }

    public void ajaxBegin() {
        Log.w(TAG, "AJAX Begin");
        Toast.makeText(context, "AJAX Begin", Toast.LENGTH_SHORT).show();
    }

    public void ajaxDone() {
        Log.w(TAG, "AJAX Done");
        Toast.makeText(context, "AJAX Done", Toast.LENGTH_SHORT).show();
    }
}

下面是AjaxHandlerActivity中的使用方式:

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    private WebView webView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        // get web view
        webView = (WebView) findViewById(R.id.web); 

        // configure web view 
        final WebSettings webSettings = webView.getSettings();
        webSettings.setBuiltInZoomControls(true);
        webSettings.setJavaScriptEnabled(true);

        webView.loadUrl("http://foo.com");

        // add javascript interface
        webView.addJavascriptInterface(new AjaxHandler(this), "ajaxHandler");

        // override onPageFinished method of WebViewClient to handle AJAX calls 
        webView.setWebViewClient(new WebViewClient() {

                @Override
                public void onPageFinished(WebView view, String url) {
                    super.onPageFinished(view, url);

                    view.loadUrl("javascript:$(document).ajaxStart(function (event, request, settings) { " +
                            "ajaxHandler.ajaxBegin(); " + // Event called when an AJAX call begins
                            "});");
                    view.loadUrl("javascript:$(document).ajaxComplete(function (event, request, settings) { " +
                            "ajaxHandler.ajaxDone(); " + // Event called when an AJAX call ends
                            "});");

            });
    }
}

主要思想来自here,并进行了一些调整。
虽然现在提交答案有点晚了,但希望这也能帮助到其他人!

avwztpqn

avwztpqn3#

最后我还是用了题中所描述的方法;
我截获了一些具体的请求,例如:然后foo://bar/get/1?callback=foobar解析URL并使用实际数据调用JavaScript回调函数。
回调函数是在URL的查询部分定义的,所以在上面的例子中是:foobar();
调用该函数很容易,只需用途:yourWebView.loadUrl("javascript:foobar('somedata')");

anauzrmj

anauzrmj4#

现在是2023年,我遇到了同样的问题。
我使用shouldInterceptRequest()方法解决了这个问题。黑客是通过过滤被拦截的请求并相应地采取行动。
shouldInterceptRequest()方法拦截在WebView上发出的所有请求。在我的例子中,我知道正在发出的确切请求,以及与请求相关联的确切URL。

@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

  String sURLPatternExpected = "";
  if (request.getUrl().toString().contains(sURLExpected)) {

    String sExactURLExpected = "";
    if (!request.getUrl().toString().equals(sExactURLExpected)) {
      //  User is going outside your expected URL.
    } else {
      //  User is going outside your expected URL.
    }

  }

  return null;
}

在上面的代码片段中,您首先检查请求URL是否与您正在查找的模式匹配。例如,如果您对http://example.com/app/resource?message=hello这样的URL感兴趣,则以上述方式进行过滤将阻止您对http://example.com/favicon.ico这样的URL进行操作。
接下来的事情是现在检查您在URL过滤组中期望的确切URL。
最后,我返回null,让WebView正常处理请求。

相关问题