chrome浏览器自从去年以来逐步去掉了对浏览器插件的支持,npapi的方案马上不可用。 当务之急要选择一个替代方案,最常用的就是扩展了。扩展程序提供了一套和本地程序交互的方案——“原生消息通信”
写本地应用的工具和语言很多,比如:C#,C++,phyon 都可以,本人对delphi熟悉一点,就说说delphi怎么接收和发送消息的吧。
Chrome扩展对原生消息通信有非常明确的说明
Chrome 浏览器在单独的进程中启动每一个原生消息通信宿主,并使用标准输入(stdin)与标准输出(stdout)与之通信。向两个方向发送消息时使用相同的格式:每一条消息使用 JSON 序列化,以 UTF-8 编码,并在前面附加 32 位的消息长度(使用本机字节顺序)。
怎么做呢?
1、background.js中定义消息
var nativeHostName='com.xxx.mytest';//chrome与本地程序通信的桥梁,根据该名称进行配置项的寻找。windows下在注册表HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts内寻找,linux下在目录/etc/opt/chrome/native-messaging-hosts/寻找该名称的json文件() //native startchrome.runtime.sendNativeMessage(nativeHostName,jsonData, function(response){ if (chrome.runtime.lastError){ console.log("lastError:" + chrome.runtime.lastError.message); } else{ console.log("recieved message: ", response.message); }});
2、新建一个Delphi控制台程序,添加标出输入和标准输出接口即可
接收数据的标准输入
function ReadInputJson():WideString;var strmInput: THandleStream; LBuffer: TBytes; resLen:Integer; sData: string;begin strmInput := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE)); try SetLength(LBuffer, 4); strmInput.ReadBuffer(Pointer(LBuffer)^,4); resLen:= PInteger(LBuffer)^; SetLength(sData, resLen); strmInput.Read(sData[1], resLen); Result := UTF8Decode(sData); finally strmInput.Free; end; end;
返回数据的标准输出
procedure WriteOutputJson(const str:String);var strmOut: THandleStream; len:Integer; json:String;begin json:=UTF8Encode(str); len:=Length(json); strmOut := THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE)); try strmOut.Write(len,4); strmOut.Write(PChar(json)^, len); finally strmOut.Free; end; end;
主要是处理UTF8编码和前32位长度,非常容易出错。