准备协议文件;
// 协议文件 MyBook.proto
syntax = "proto3"; //protobuf协议版本声明
package test; //包名声明(可选),类似于namespace
message MyBook { //这里定义了一个消息MyBook,包含3个成员id_,price_,date_
int32 id_ = 1;
float price_ = 2;
string date_ = 3;
}
下载并安装最新版node.js,默认安装即可;
https://nodejs.org/dist/v14.16.0/node-v14.16.0-x64.msi
全局安装依赖 require,browserify,google-protobuf
npm install -g require
npm install -g browserify
npm install -g google-protobuf
下载win端的协议文件编译程序,只需要使用里面的可执行程序protoc.exe
https://github.com/protocolbuffers/protobuf/releases/download/v3.15.6/protoc-3.15.6-win64.zip
编译协议文件,生成原始js文件MyBook_pb.js
protoc --js_out=import_style=commonjs,binary:. MyBook.proto
编写“导出”文件MyBook-export.js, 放在与MyBook_pb.js同级目录;
var mybook = require("./MyBook_pb");
module.exports = {
DataProto: mybook
}
使用browserify打包工具,配合“导出文件”将原始js文件和依赖库打包成最终js文件
browserify MyBook-export.js > mybook.js
原生JS代码对数据进行编解码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./mybook.js"></script>
</head>
<body>
<button id="btn">测试</button>
<script>
document.getElementById('btn').onclick = function () {
var httpReq = new XMLHttpRequest();
// httpReq.open("GET", "/api/cgi-bin/protobuf-test", true);
httpReq.open("POST", "/api/cgi-bin/protobuf-test", true);
// httpReq.open("GET", "/api/cgi-bin/protobuf-test", true);
httpReq.responseType = "arraybuffer";
// POST方法时,必须设置请求头
httpReq.setRequestHeader("Content-Type",
"application/octet-stream");
httpReq.onreadystatechange = function () {
if (httpReq.readyState == 4 && httpReq.status == 200) {
console.log(httpReq.response);
var str = proto.test.MyBook.deserializeBinary(httpReq.response)
console.log(str)
//解析数据
console.log(str.getId());
console.log(str.getPrice());
console.log(str.getDate());
}
}
// httpReq.send();// GET
// 序列化数据并发送
var obj = new proto.test.MyBook();
obj.setId(1);
obj.setPrice(42.2);
obj.setDate("2021-09-09");
var sendData = obj.serializeBinary();
httpReq.send(sendData);
}
</script>
</body>
</html>
关于setId(),setPrice(),setDate()等API的命名规律,我暂时还确定不了。比较笨的方法就是在编译生成的源码中搜索了。
后台CGI程序将上传数据修改后,浏览器设置输出:
关于后台接口:/api/cgi-bin/protobuf-test
使用vscode开发,安装live-server并设置proxy;