WebView与JS、Ajax跨域问题

》1.webview其实就是一个浏览器,而是否允许跨域,是由你访问的服务器控制的(默认不允许),如果是nginx,配置如下:
http {
  ......
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Headers X-Requested-With;
  add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
  ......
}
其实就是在Http响应头中加了点东西,其他的服务器也类似这样。
跨域的问题是javascript限制的。和webview或UIWebview都没有关系。
当然跨域的解决方案有很多,可以自行google或百度之。
》2.Finally I've found the answer after 3 Long days. 
the problem was in the page that I request which have this code:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
in the response which conflict with android webview and doesn't work with jquery selectors ... Don't know why!!!
but when I removed the above code from response the page and its ajax works fine.
》3。
if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) 
  wv.getSettings().setAllowUniversalAccessFromFileURLs(true);
But if you want to compile against and support systems below API11 you have to add the following:


if (Build.VERSION.SDK_INT >= 16) {  
    Class<?> clazz = webView.getSettings().getClass();
    Method method = clazz.getMethod("setAllowUniversalAccessFromFileURLs", boolean.class);
    if (method != null) {
        method.invoke(webView.getSettings(), true);
    }
}
Different subdomains are not also allowed. Chrome was acting really wierd ( it was working ok for my "get" request , but was changing my "post" request to "OPTIONS" request ), it took me a lot time to figure out the error. The error was gone when i put the services and client code under the same subdomain.
Web services requires POST so i couldn't use JSONP and GET. Thanks for your helps, i think the best way, setting Access-Control-Allow-Origin: *
》4. 有多少次做webapp的时候,写js会碰到 XMLHttpRequest cannot load http://abc Origin http://def  is not allowed by Access-Control-Allow-Origin. 跨域问题一直搞得很烦,不知道W3C怎么想的,安全上又不能完全避免,写程序又极不方便。
之前做浏览器时可以修改浏览器而实现,而在android上查了居然没api。查阅代码树发现webviewcore有相关接口,又被java的private修饰符给挡住(高级语言就是喜欢整一套规范,搞得n多人成天讨论规范,而忘了编程的思想)。
吐槽完毕,思路及代码如下
思路:
访问android WebView private 对象 WebViewCore mWebViewCore,调用 mWebViewCore的private 方法nativeRegisterURLSchemeAsLocal,把http和https忽悠成本地访问。 XMLHttpRequest即可自由跨域。
注:android 4.1煎饼以上还需要设置WebSettings.setAllowUniversalAccessFromFileURLs(true) 

代码从WebView继承一个新类,增加一个开启跨域函数:
public class WokaoWebView extends WebView{
构造和其他函数省略.....
public void enablecrossdomain()
{
try{
Field field = WebView.class.getDeclaredField("mWebViewCore");
field.setAccessible(true);
Object webviewcore=field.get(this);
Method method=webviewcore.getClass().getDeclaredMethod("nativeRegisterURLSchemeAsLocal", String.class);
method.setAccessible(true);  
method.invoke(webviewcore, "http");
method.invoke(webviewcore, "https");
}
catch(Exception   e){
Log.d("wokao","enablecrossdomain error");
e.printStackTrace();
}
}
}

~~~~~~~~~
使用时,
WokaoWebView _web_app= (WokaoWebView)webapp_desktop.findViewById(R.id.webapp_page);
_web_app.enablecrossdomain();
_web_app.loadUrl("xxxx");
~~~~~~~~~~~~~~~~~~~~~~~~~~
android 4.1webview改动比较大。调用参数也多了一个,代码如下
public void enablecrossdomain41()
{
try{
Field webviewclassic_field = WebView.class.getDeclaredField("mProvider");
webviewclassic_field.setAccessible(true);
Object webviewclassic=webviewclassic_field.get(this);
Field webviewcore_field=webviewclassic.getClass().getDeclaredField("mWebViewCore");
webviewcore_field.setAccessible(true);
Object mWebViewCore=webviewcore_field.get(webviewclassic);
Field nativeclass_field=webviewclassic.getClass().getDeclaredField("mNativeClass");
nativeclass_field.setAccessible(true);
Object mNativeClass=nativeclass_field.get(webviewclassic);

Method method=mWebViewCore.getClass().getDeclaredMethod("nativeRegisterURLSchemeAsLocal",new Class[] {int.class,String.class});
method.setAccessible(true);
method.invoke(mWebViewCore,mNativeClass, "http");
method.invoke(mWebViewCore,mNativeClass, "https");
}
catch(Exception   e){
Log.d("wokao","enablecrossdomain error");
e.printStackTrace();
}
}

总结:最后一点解决了问题。。。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值