Haskell WARP/WAI 服务器无法响应来自 Android 嵌入式 WebView 的 AJAX 调用
Haskell WARP/WAI server fails to respond to AJAX calls from Android embedded WebView
更新 3 当到达端点 http://httpbin.org/user-agent 时,请求 returns成功。所以我的 Haskell Warp+WAI 应用程序服务器出了点问题。
有什么想法可以使服务器 API 调用适用于大多数浏览器,但不适用于 Android WebView?
澄清一下,我 没有做任何跨域请求。 我在这里看到了数百个关于此的问题,但我的 AJAX 请求是针对WebView 已加载的同一域。
更新 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.
我想知道我的服务器是否有问题?我正在使用一个不寻常的服务器,基于 Haskell 的带有 WAI 的 WARP。 ...但是为什么在所有其他浏览器中一切正常?
UPDATE 我做了一些调试,这是我在下面显示的 AJAX 调用中遇到的错误(一个基本的 'is server up?' GET 查询):
error: NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://www.example.net:2753/ping'
不用说确切的 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 调用中,我尝试了 async 和 cache 的四种可能组合; none工作。
原来问题出在 WebView 通过 IP 地址加载页面,而 JavaScript 通过域名引用它。据我所知,不这样做可能是常识;但非 WebView 客户端处理它的方式还行,这让我早早排除了它可能存在的问题。
更新 3 当到达端点 http://httpbin.org/user-agent 时,请求 returns成功。所以我的 Haskell Warp+WAI 应用程序服务器出了点问题。
有什么想法可以使服务器 API 调用适用于大多数浏览器,但不适用于 Android WebView?
澄清一下,我 没有做任何跨域请求。 我在这里看到了数百个关于此的问题,但我的 AJAX 请求是针对WebView 已加载的同一域。
更新 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.
我想知道我的服务器是否有问题?我正在使用一个不寻常的服务器,基于 Haskell 的带有 WAI 的 WARP。 ...但是为什么在所有其他浏览器中一切正常?
UPDATE 我做了一些调试,这是我在下面显示的 AJAX 调用中遇到的错误(一个基本的 'is server up?' GET 查询):
error: NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://www.example.net:2753/ping'
不用说确切的 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 调用中,我尝试了 async 和 cache 的四种可能组合; none工作。
原来问题出在 WebView 通过 IP 地址加载页面,而 JavaScript 通过域名引用它。据我所知,不这样做可能是常识;但非 WebView 客户端处理它的方式还行,这让我早早排除了它可能存在的问题。