1. 概述
1.1 問題描述
FineBI 透過各種樣式如表格、圖表等來呈現資料,進行統計分析。這些資料表格或圖表,使用者在開發系統的時候也可以自己編程來實現,但是工作量大,維護難。
1.2 實現思路
FineBI 是基於 B/S 架構的瀏覽器/伺服器模式,現在使用者開發的系統基本上趨向於 B/S 架構的瀏覽器/伺服器模式,因此有些頁面完全可以直接採用 Web 頁面嵌入式整合的簡易方式完成整合。
透過整合,使用者從自己的系統透過連結使用瀏覽器存取 FineBI 的伺服器,進而在自己系統內呼叫 FineBI 的 Web 頁面,來實際嵌入式整合。
2. 範例
範例檔案:login.html
2.1 關閉 Security Headers
由於平台安全限制,FineBI 在整合時需要將管理系統>安全管理>安全防護中的「Security Headers」關閉才可跨域,如下圖所示:
2.2 HTML 檔案編寫
2.2.1 具體步驟
1)代碼內容如下所示:
注:代碼中範本位址為完整位址,使用者可開啓 範本認證 避免出現其他人得到範本完整 URL 查看範本資料的情況。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"> </script> <script type="text/javascript"> var url = "http://localhost:37799/webroot/decision"; function loginFR(callback) { var username = document.getElementById("username").value; var password = document.getElementById("password").value; jQuery.ajax({ url: url + "/login/cross/domain?fine_username=" + username + "&fine_password=" + password + "&validity=-1", type: "GET", dataType:"jsonp", timeout:10000, success:function(data) { alert(JSON.stringify(data)); if (data.status === "success") { alert("successful!"); } else if (data.status === "fail"){ alert("login fail!"); } callback && callback(data.accessToken); }, error:function(){ alert("login error!"); } }); } function GetList(token) { var i=0; jQuery.ajax({ url: url + "/v5/api/dashboard/user/info?op=api&cmd=get_all_reports_data&fine_auth_token=" + token, type: "GET", timeout: 10000, dataType: "jsonp", success:function(res) { for(;i < res.data.dashboards.length;i++) { document.write(JSON.stringify(res.data.dashboards[i].name)+"<br>"); } }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert(XMLHttpRequest+"/"+textStatus+"/"+errorThrown); } }); } function NewDemo(token) { var name = prompt("name",""); var id = ""; var dir = {name: name, catalog: []} var flag = 0; jQuery.ajax({ url: url + "/v5/api/platform/dashboard/reports?dir=" + window.encodeURI(JSON.stringify(dir)) + "&fine_auth_token=" + token, type: "GET", dataType:"jsonp", timeout:10000, success:function(res) { if(name != "") { for (var key in res) { if(key=="error") { flag=1; } } if(flag==0) { window.location.href = url + "/v5/design/report/" + res.data.id + "/edit"; } else { alert("error!"); } } else { alert("name is empty"); } }, error:function(XMLHttpRequest,textStatus,errorThrown){ //alert(JSON.stringify(data)); alert(XMLHttpRequest+"/"+textStatus+"/"+errorThrown); } }); } </script> </head> <body> <form id="loginForm" name="loginForm" method="post" action="index.html"> <table> <tbody> <tr class="prop"> <td class="name"><label> Username</label></td> <td class="value"><input id="username" type="text" name="username" value="admin" /></td> </tr> <tr class="prop"> <td class="name"><label> Password</label></td> <td class="value"><input id="password" type="password" name="password" value="1" /></td> </tr> <tr> <td><input id="btn1" type="button" name="b1" value="login" onclick="loginFR();" /></td> </tr> <tr> <td><input id="btn2" type="button" name="b2" value="login & get list" onclick="loginFR(GetList);" /></td> </tr> <tr> <td><a href="http://localhost:37799/webroot/decision/v5/design/report/f987404aa556460995c4519e470c5836/view"> <input id="btn3" type="button" name="b3" value="open" onclick="loginFR();" /> </a></td> </tr> <tr> <td><input id="btn4" type="button" name="b4" value="new" onclick="loginFR(NewDemo);" /></td> </tr> </tbody> </table> <div class="actionButtons"> </div> </form> </body> </html>
注:以上檔案中 URL 位址為 FineBI 初始預設位址:http://localhost:37799/webroot/decision,可根據需要修改為自身工程的位址及埠;代碼中的帳號、密碼需要根據實際情況修改。
2)將 HTML 檔案命名為 login.html ,放到%BI_HOME%\webapps\webroot下。
2.2.2 代碼介紹
FineBI 在進行嵌入式整合時一般分為兩步:獲取 Token 和呼叫其他相關 API 。
1)獲取 Token:API 在呼叫需要先獲取 Token 資訊。FineBI 透過 JSONP 獲取跨域資料,可以透過以下方法來獲取 Token 。代碼如下所示:
// 獲取token方法
function loginFR(callback) {
// 頁面上的帳號密碼輸入框值
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
// 登入api
jQuery.ajax({
url: url + "/login/cross/domain?fine_username=" + username + "&fine_password=" + password + "&validity=-1", // 登入url
type: "GET",
dataType:"jsonp",
timeout:10000,
success:function(data) {
alert(JSON.stringify(data));
if (data.status === "success") {
alert("successful!");
} else if (data.status === "fail"){
alert("login fail!");
}
// 獲取到token
callback && callback(data.accessToken);
},
error:function(){
alert("login error!");
}
});
}
2)呼叫其他相關 API:獲取到 Token 後可以呼叫其他 API ,比如獲取範本列表,建立儀表板,代碼如下所示:
// 獲取範本列表方法
function GetList(token) {
var i=0;
jQuery.ajax({
url: url + "/v5/api/dashboard/user/info?op=api&cmd=get_all_reports_data&fine_auth_token=" + token,
type: "GET",
timeout: 10000,
dataType: "jsonp",
success:function(res) {
for(;i < res.data.dashboards.length;i++) {login.html
document.write(JSON.stringify(res.data.dashboards[i].name)+"
");
}
},
error:function(XMLHttpRequest,textStatus,errorThrown){
alert(XMLHttpRequest+"/"+textStatus+"/"+errorThrown);
}
});
}
// 建立儀表板方法
function NewDemo(token) {
var name = prompt("name","");
var id = "";
var dir = {name: name, catalog: []}
var flag = 0;
jQuery.ajax({
url: url + "/v5/api/platform/dashboard/reports?dir=" + window.encodeURI(JSON.stringify(dir)) + "&fine_auth_token=" + token,
type: "GET",
dataType:"jsonp",
timeout:10000,
success:function(res) {
if(name != "") {
for (var key in res) {
if(key=="error") {
flag=1;
}
}
if(flag==0) {
window.location.href = url + "/v5/design/report/" + res.data.id + "/edit";
} else {
alert("error!");
}
} else {
alert("name is empty");
}
},
error:function(XMLHttpRequest,textStatus,errorThrown){
//alert(JSON.stringify(data));
alert(XMLHttpRequest+"/"+textStatus+"/"+errorThrown);//
}
});
}
注:此處的所有請求都需要帶上請求型別:dataType: "jsonp",否則請求無法處理。
注:FineBI 中 URL 傳遞 JSON 對像,有些伺服器不支援 JSON 物件的 URL ,因此需要把 JSON 型別的 URL 參數值先進行編碼encodeURIComponent()。例如:
2.3 效果展示
啟動 FineBI 工程,存取http://localhost:37799/webroot/login.html,如下圖所示:
注:第一個 login 按鈕,代表登入工程;點選第一個 login 按鈕,再點選第三個 open 按鈕,則不會進入登入頁提示登入的。