Xilium CefGlue 利用XHR实现JS调用C#方法

作者: 时间: 2014-11-14 分类: 技术文章 | 0条评论 |

引言:Xilium CefGlue是个不错的cef扩展工程,托管地址在这里 https://bitbucket.org/xilium/xilium.cefglue/wiki/Home

当然它还有很多工作要做,这里介绍一下怎样利用XHR实现Js调用c#方法。代码已经在官方Demo里,只是没有中文资料,英文资料也几乎没有,这里只是把它挖出来讲一下,本人毫无技术含量。ps:感谢热心的@dmitry.azaraev邮件耐心回复。

本文参考自 http://www.cnblogs.com/liulun/archive/2013/03/18/2874276.html,建议先阅读该系列教程。

什么是XHR

XMLHttpRequest (XHR) is an API available to web browser scripting languages such as JavaScript. It is used to send HTTP or HTTPSrequests to a web server and load the server response data back into the script.[1] Development versions of all major browsers support URI schemes beyond http: and https:, in particular, blob: URLs are supported.[2]

在这里,XHR可以向CefGlue浏览器发送请求,并接收回复,简单的字符串即可通过Post传递,如果是复杂对象,可以使用Json转换后传递。

CefGlue提供的API

RegisterSchemeHandlerFactory(string schemeName, string domainName, CefSchemeHandlerFactory factory)

该方法位于CefRuntime,在启动Initialize后使用。其向浏览器注册一个Scheme处理工厂。

三个参数:

schemeName:scheme名;

domainName:使用域 的名称,这一个参数比较重要,在js中我们需要向这个地址发送Post请求,可以随便填,比如 “testdomain”,那么在js中请求的地址是 “http://testdomain/”;

factory:处理工厂,需要来装配一个处理handle。

C#端需要做的两项工作

1.新建一个类DumpRequestResourceHandler,继承自CefResourceHandler,有六个函数需要我们继承,这里只用到前面三个。

 C# Code By WuleBa.COM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
protected override bool ProcessRequest(CefRequest request, CefCallback callback)

{

    
//

    return true;

}



protected override void GetResponseHeaders(CefResponse response, out long responseLength, out string redirectUrl)

{

    
//

    responseLength = –1;

    redirectUrl = 
null;

}



protected override bool ReadResponse(Stream response, int bytesToRead, out int bytesRead, CefCallback callback)

{

    
//

    bytesRead = 0;

    
return false;

}



protected override bool CanGetCookie(CefCookie cookie)

{

    
return false;

}



protected override bool CanSetCookie(CefCookie cookie)

{

    
return false;

}



protected override void Cancel()

{

}

2.新建一个类DemoAppSchemeHandlerFactory,继承自CefSchemeHandlerFactory

这个就是我们需要在注册时用到的工厂,继承他的Creat函数,返回我们上面建的DumpRequestResourceHandler实例即可。

 C# Code By WuleBa.COM
1
2
3
4
protected override CefResourceHandler Create(CefBrowser browser, CefFrame frame, string schemeName, CefRequest request)

{

    
return new DumpRequestResourceHandler();

}

Js端需要做的工作

js端需要做的就是创建一个XmlHttpRequest,向之前注册的地址发请求即可,代码在园子里很多,随便搜搜就能找到。

 JavaScript Code By WuleBa.COM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script type=“text/javascript”>

function CreateXmlHttpRequest() {

    
var xmlHttp = null;

    
if (window.XMLHttpRequest) {

// For Mozilla, Safari, …

xmlHttp = new XMLHttpRequest();

    }

    
else if (window.ActiveXObject) {

// For Internet Explorer

xmlHttp = new ActiveXObject(“Microsoft.XMLHTTP”);

    }

    
return xmlHttp;

}

function testPost() {

    
var xmlHttp = CreateXmlHttpRequest();

    
var para = “id=testid&name=testname”;

    xmlHttp.open(
“POST”“http://testdomain/”false);

    xmlHttp.setRequestHeader(
‘Content-Type’‘application/x-www-form-urlencoded’);

    xmlHttp.send(para);

    
var result = xmlHttp.status;

    
if (xmlHttp.readyState == 4) {

if (result == 200) {

    
var response = xmlHttp.responseText;

    alert(response);

}

    }

}

</script>

这里的js只是举个栗子,你也可以用异步的请求之类的,不要在意这些细节。

如何接收Post数据

回到DumpRequestResourceHandler 的ProcessRequest方法,post过来的数据就在request.PostData里,GetElements()以后把字节数组转成字符串即可。

怎么返回数据给Js

在DumpRequestResourceHandler的GetResponseHeaders方法里,你需要回复一个接收成功的状态:

 C# Code By WuleBa.COM
1
2
3
response.MimeType = “text/html”;

response.Status = 
200;

response.StatusText = 
“OK, hello from handler!”;

并写一些头信息:

 C# Code By WuleBa.COM
1
2
3
4
var headers = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);

headers.Add(
“Cache-Control”“private”);

headers.Add(
“Access-Control-Allow-Origin”,“*”);

response.SetHeaderMap(headers);

注意这一句代码:headers.Add(“Access-Control-Allow-Origin”,”*”); 因为跨域的问题,如果你的html在本地,XHR的返回永远都是0并没有数据。这里是允许所有的跨域访问,存在安全问题暂时不表。

你可以在这里找到更多资料:

http://stackoverflow.com/questions/15977151/loading-local-content-through-xhr-in-a-chrome-packaged-app

http://blog.csdn.net/hfahe/article/details/7730944

在ReadResponse方法里把数据写回去:

response.Write(responseData, pos, bytesToRead);

是不是跑题了?一直都没讲怎么调用c#方法啊?你特么是在逗我吗?
……

我是这样做的,在js的post数据里带参数,比如我要调用的c#方法是A类中的test(string msg);

我的post参数这样传:

var para = “method=test&msg=testtext”;

ProcessRequest拿到参数以后就知道了函数的名字和参数,将A类中的test方法反射出来执行,如需要返回值,参考上面的方法即可。

这样做存在一些问题,比如函数无法重载、js和c#类型转换之类的。

我这边项目用到的基本公开给js的函数都很明确,没有重载;另外有复杂对象,也能用json来解决。暂时绕开了这些问题,当然也不是很难解决。

官方的代码实例可以在这里找到:

Xilium.CefGlue.Demo.DemoApp 78行,注册scheme

Xilium.CefGlue.Demo的SchemeHandler文件夹下的DemoAppSchemeHandlerFactory、DumpRequestResourceHandler两个类。

如果有不明白的地方,可以慢慢看代码。

本文采用 CC协议 发布,转载请注明:转载自 吾乐吧软件站

本文链接地址:http://www.wuleba.com/?p=26359

发表评论


微软MSDN资源免费订阅,MSDN 我告诉你