天天看點

利用fodi給onemanager前後端分離(1):将fodi py後端安裝在騰訊免費cloudbase

本文關鍵字:将fodi py後端安裝在騰訊cloudbase

在前面《利用onemanager配合公有雲做站和nas》中,我們提到onemanager是個可以裝在騰訊雲函數API網關或cloudbase上作為雲函數的産品,onemanager php backend它本身也是調用onedrive的api,在前面《owncloud微網誌式記事本》《wp2oc fileshare》中我們也提到這種web api的修改定制。最近的《打造小程式版本公号和自托管的公号:miniblog》也是這種例子,後端cloudfuntion化,前端miniprogram則被部署到微信,,前後端分離和web api化調用是早已流行的趨勢。

在《利用onemanager配合公有雲做站和nas》中我們也提到要繼續為onemanager找提高浏覽體驗用的緩存方案靜态化方案,onemanager拉取檔案清單延遲高體驗不佳(這種延遲一部分就是它本身前後端不分離,一次傳回結果混合了渲染html的客端邏輯,用戶端也沒有 ajax,另一部分是onemanager這類程式本身也是使用api的,傳回結果來自OD本身是外部的,其隻有有限的doctrine緩存技術,沒有像混合雲那樣的多樣化混合本地和遠端雲結果建構高效網站體驗的能力),這次我們找到了fodi。其前後分離和用戶端ajax技術,體驗比單純的onemanger要好得多,fodi分離的好處是,相當大部分邏輯都被放在了用戶端。如浏覽檔案,伺服器僅負責一次傳回一些json資料,現在的浏覽器本身一般也有本地緩存存儲。,整個可以帶來類似pwa,js based react native app的效果,這也是fodi名字中的fast的理念技術基礎。

我們的目标是使od像fodi那樣前後端分離,并研究嘗試讓它接上fodi前端的方法。----- 等等,直接用fodi前後端一套流不香嗎?fodi有二個後端,一個backend_cf for cloudflare,一個py for 雲函數,fodi py後端輸出的是加密的json對我們接下來的研究不夠直覺化(除非chrome f12),而nodejs端直接輸出直覺的json結果,但nodejs runtime(<=10.15)又不支援addeventlistener(),它是cloudflare用的,是以我們打算用改造onemanager的結果來适配fodi前端。使之成為fodi的php backend。

注意:Fodi有部分預拉取清單功能,是以産生的雲函數調用會比較多(是以推薦将fodi裝到vps),但是om的缺點是雲函數調用流量方面也相對較多。

這裡還是介紹将fodi後端部署到cloudbase的方法

上傳和修改後端邏輯:

用cloudbase-cli送出backend-py:

{
  "envId": "default-4gpm7vnrb911600e",
  "functionRoot": "functions",
  "functions": 
  [{
    "name": "fodi",    //fodi就是backend-py
    "timeout": 6,
    "runtime": "Python3.6",
    "memorySize": 128,
    "installDependency": true,
    "handler": "index.main_handler"
  }]
}           

以下保證要使用

https://xxxx.service.tcloudbase.com/fodi

形式的調用路徑(背景的接入路徑定義):

def router(event):
    """對多個 api 路徑分發
    """
    door = 'https://' + event['headers']['host']
    print('door:'+door)
    func_path = '' #event['requestContext']['path'] //置空
    print('func_path:'+func_path)
    
    api = event['path'].replace(func_path, '').strip('/') 
    api_url = door + '/fodi' + event['path']  //加一個fodi串

    queryString = event['queryStringParameters']  //這裡改
    body = None
    ......           

弄好後,通路上面的接入路徑,僅/fodi,輸出path error和後面一長串東西就代表伺服器搭建正常,

擷取refresh token

然後就是那個refreshtoken的擷取,

http://scfonedrive.github.io

已經挂掉了,我們可以自建,先在某網站下建一個get.html:

<html><meta charset=utf-8><body><h1>Error</h1><p>Please set the <code>refresh_token</code> in environments<br>
    <a href="" id="a1">Get a refresh_token</a>
    <br><code>allow javascript</code>
    <script>
        url=window.location.href;
        if (url.substr(-1)!="/") url+="/";
        url="https://login.partner.microsoftonline.cn/common/oauth2/v2.0/authorize?scope=https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2FFiles.ReadWrite.All+offline_access&response_type=code&client_id=04c3ca0b-8d07-4773-85ad-98b037d25631&redirect_uri=https://scfonedrive.github.io&state="+encodeURIComponent(url);
        document.getElementById('a1').href=url;
        //window.open(url,"_blank");
    </script>
    </p></body></html>

如果是國際版url換成:
 url="https://login.microsoftonline.com/common/oauth2/v2.0/authorize?scope=https%3A%2F%2Fgraph.microsoft.com%2FFiles.ReadWrite.All+offline_access&response_type=code&client_id=4da3e7f2-bf6d-467c-aaf0-578078f0bf7c&redirect_uri=https://scfonedrive.github.io&state="+encodeURIComponent(url);
           

再在根下建一個index.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>OneManager jump page</title>
    </head>
    <body>
        <a id="direct">No link here!</a><br>
        If not auto jump, click the link to jump.<br>
        如果長時間未跳轉,請點選上方連結繼續安裝。<br>
        <label id='test1'></label>
        <script>
                  var q = new Array();
            var query = window.location.search.substring(1);
            //document.getElementById('test1').innerHTML=query;
            var vars = query.split("&");
            for (var i=0;i<vars.length;i++) {
                var pair = vars[i].split("=");
                q[pair[0]]=pair[1];
            }
            var url = q['state'];
            var code = q['code'];
            if (!!url && !!code) {
                url = decodeURIComponent(url);
                if (url.substr(-1)!="/") url+="/";
                var lasturl = url+"?authorization_code&code="+code;
                document.getElementById('direct').innerText = lasturl;
                document.getElementById('direct').href = lasturl;
                window.location = lasturl;
            } else {
                var str='Error! 有誤!';
                if (!url) str+='No url! url參數為空!';
                if (!code) str+='No code from MS! 微軟code為空!';
                document.getElementById('test1').innerHTML=str+'<br>'+decodeURIComponent(query);
                alert(str);
            }
        </script>
    </body>
</html>           

把get中scfonedrive.github.io換成你的index.html所在的網站位址,(之後保證把py後端中用于認證的位址和那個clientid,clientsecret替換用你自己建立的一個,具體方法見我前面的一些文章)

調用後結果顯示在url中(整個頁面顯示404是沒有處理結果的php後端,除非你把

https://github.com/qkqpttgf/OneDrive_SCF

部署在index.html所在的網站),分辨複制即可。

安排好後端和refreshtoken後,調用接入路徑/fodi/fodi/,輸出看到其輸出的加密的json結果,就代表refreshtoken也正常了。

開始部署前端,可以另外一個網站,能托管html的就行。也可以在後端另起一函數,部署如下index.py:

#!/usr/bin/env python
# -*- coding:utf-8 -*-


def main_handler(event, context):
    f = open("./front.html", encoding='utf-8')
    html = f.read()
    return {
        "isBase64Encoded": False,
        "statusCode": 200,
        "headers": {'Content-Type': 'text/html; charset=utf-8'},
        "body": html
    }           

front.html當然是配置好的那個前端檔案。

如果你fodi前端調用發生for each,length之類的提示錯誤,往往是refresh token沒擷取對。如果發生跨域錯誤(chrome f12可看到),則在後端面闆中需要配置一條用戶端網站的安全域名。

整個代碼也較大,我們稍後将3rd依賴庫精簡掉,把那個加密邏輯去掉讓輸出常态化。

(此處不設回複,掃碼到微信參與留言,或直接點選到原文)

利用fodi給onemanager前後端分離(1):将fodi py後端安裝在騰訊免費cloudbase