【问题标题】:Haskell WARP/WAI server fails to respond to AJAX calls from Android embedded WebViewHaskell WARP/WAI 服务器无法响应来自 Android 嵌入式 WebView 的 AJAX 调用
【发布时间】:2017-06-30 10:35:36
【问题描述】:

UPDATE 3 当到达端点http://httpbin.org/user-agent 时,请求成功返回。所以我的 Haskell Warp+WAI 应用服务器出了点问题。

有什么想法可以使服务器 API 调用适用于大多数浏览器,但不适用于 Android WebView?


澄清一下,我没有执行任何跨域请求。我在这里看到了数百个问题,但我的 AJAX 请求是针对 WebView 加载的同一个域。 p>

UPDATE 2 我没有使用 jQuery,而是使用了更基本的 xhr 方法,如下所示:

function pingServer()
{
  var xhr = new XMLHttpRequest();
  xhr.open('get', URL + 'ping');

  // Track the state changes of the request.
  xhr.onreadystatechange = function()
  {
    var DONE = 4; // readyState 4 means the request is done.
    var OK   = 200; // status 200 is a successful return.

    if (xhr.readyState === DONE)
    {
      if (xhr.status === OK)
      {
        $('#submitDialog p').text(xhr.responseText + ' : ' + xhr.status);
      }
      else
      {
        $('#submitDialog p').text(xhr.responseText + ' : ' + xhr.status);
      }
    }
  };
  xhr.send(null);
}

仍然没有运气。 xhr.responseText 为空白,xhr.status 为 0。

我想知道我的服务器是否有问题?我正在使用一个不寻常的服务器,即带有 WAI 的基于 Haskell 的 WARP。 ...但是为什么在其他所有浏览器中一切正常?


更新我做了一些调试,这是我在下面显示的 AJAX 调用中遇到的错误(一个基本的“服务器启动了吗?”GET 查询):

错误:NetworkError:无法在“XMLHttpRequest”上执行“发送”:无法加载“http://www.example.net:2753/ping

不用说确切的 URL(我正在使用的真实 URL,而不是示例)在任何移动或桌面浏览器中都可以正常加载 - 只有 Android WebView 有这个问题!


我有一个简单的 Android 应用;只是一个加载远程 URL(不是本地资源)的 WebView。它工作正常,除了我所有的 AJAX 调用立即调用它们的错误回调。我正在三星 Galaxy S6 上进行测试,并将应用程序构建到 SDK 21。

这是我的第一个 AJAX 调用(失败)的样子;其他人使用相同的属性:

$.ajax(
{
  url: URL + 'ping',
  cache: false,
  async: false,
  timeout: 5000,
  error: fail,
  success: transmitScore
});

当然,transmitScore()fail() 在范围内的其他地方定义。

这是我的 WebView 的设置:

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.Locale;

public class Example extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.main);

        WebView wv = (WebView) findViewById(R.id.webview);

        wv.setWebViewClient(new WebViewClient()
        {
            public void onPageFinished(WebView v, String s)
            {
                v.loadUrl("javascript: setLang('" +
                    Locale.getDefault().getLanguage() + "')");
            }
        });
        wv.getSettings().setJavaScriptEnabled(true);
        wv.loadUrl("http://example_url_for_privacy:2753/application");
    }
}

有什么想法吗? AJAX 调用在桌面 Chrome 和 Android Chrome 中运行良好。

我在这里看到很多关于 AJAX 调用需要跨域权限的本地资源文件的问题,但这不是我的情况。所有资源都在远程服务器上,所有 AJAX 调用都转到它。

我也尝试将我的 WebView 设置为使用 WebChromeClient,但没有任何区别。我相信现在它是 WebViews 的默认设置。在 AJAX 调用中,我尝试了 asynccache 的四种可能组合;没有工作。

【问题讨论】:

  • @Sacheie ,尝试添加一个onerror 事件处理程序,它应该会提醒错误。让我知道
  • @SagarV,我不确定 onerror() 是否提供任何额外的错误信息 - 在我看来它就像一个回调,因此您不必显式检查 xhr 属性来检测错误。我不知道如何获得比 xhr.responseText 为空白且 xhr.status 为 0 的事实更详细的错误信息。
  • @Ryad URL 未使用 SSL。如果是的话,为什么该请求会在桌面浏览器(和 Android 版 Chrome)上运行。我在 Manifest 中有 Internet 访问权限(否则为什么页面会加载?) - 我需要 AJAX 的其他权限吗?
  • 可能值得尝试另一个端点,比如httpbin.org/anything,看看响应是什么。
  • 我会尝试添加标题,看看它们是否有所作为。

标签: javascript haskell xmlhttprequest haskell-wai haskell-warp


【解决方案1】:

原来问题在于 WebView 是通过 IP 地址加载页面,而 JavaScript 通过域名引用它。据我所知,不这样做可能是常识。但是非WebView 客户端处理它的方式很好,让我尽早排除了它可能存在的问题。

【讨论】:

  • 是的,通常总是使用域名,除非你有特殊的理由不这样做。您的问题可能是请求标头中缺少或不正确的主机字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-24
相关资源
最近更新 更多