2020年6月20日 星期六

[Javascript] Shopify App - 修正 location.replace 與 GA 追蹤碼 utm_* 的應用

認真使用 Shopify 大概也有一個多月了,使用了一些付費 Shopify App 在做本地化加強,發現這些第三方 app 還滿善用 variant 機制,原先是拿來設計一個商品有多種顏色等用途,現在則是應用在多儲存一些在地化的資訊。

因此,當發現需要轉化成在地化資訊時,會透過接近導網址架構,多添加 variant 資訊:

var new_url = window.location.protocol + '//' + window.location.host + window.location.pathname + '?variant=' + variant_id;

然而這樣的小機制,卻把 utm_* 的追蹤碼都給去掉了 XD 所以在幫他補強一下:

var new_url = window.location.protocol + '//' + window.location.host + window.location.pathname + '?variant=' + variant_id;

if (window.location && window.location.href) {
var m = window.location.href.match(/[\?&]([^=]+=[^&]+)/g);
if (m) {
var params = null;
for (var i=0; i<m.length ; ++i) {
if (m[i].indexOf('utm_') > 0) {
if (params == null) {
params = m[i].substr(1);
} else {
params += '&' + m[i].substr(1);
}
}
}
if (params != null) {
new_url += '&' + params;
}
}
}

收工!

2020年6月7日 星期日

[PHP] 解決 CodeIgniter 4 Command line 輸出緩衝/不即時的問題 (ob_start / ob_end_flush) @ macOS 10.15

有點忘記了,好像在 CodeIgntier 3 (CI3) 建置 Command line 運行的任務時,可以很即時看到運算的輸出結果(預設是 testing mdoe?),但在 CI 4 時,卻必須等到所有任務都做完了,才會一次輸出結果。這對於在 Jenkins 系統運行時,無法時看到運行過程是很不方便的。

追蹤 CI 4 的架構,起因是 system/CodeIgniter.php:run 中,運行時呼叫了 Events::trigger('pre_system'); ,在 app/Config/Events.php 可以看到定義了 pre_system 的工作內容,大意就是當 ENVIRONMENT 不是 testing 時,就會開啟 ob_start 使用機制。

在 CI 架構上,使用 ob_start 也有個好處,那就是寫一些網頁服務時,有時是內容產出跟 header 送出夾雜在一起。當在 PHP 使用 header 送出資料時,是不允許前面已經輸出過資料的。這時靠 ob_start / ob_end_flush 應用,就可以完美排除這種問題。

回過頭來,面對 command line 的任務,若想要排除 ob_start 的影響,可以試著包裝一個輸出訊息的函式,並在裡頭輸出完資料後,再靠這兩段補強輸出資料,如:

function debug($message) {
echo "[DEBUG] $message\n";
while (\ob_get_level() > 0)
\ob_end_flush();
}

或是乾脆在負責 Command line 任務的建構子中,直接靠 ob_get_level 和 ob_end_flush 清掉輸出緩衝的設計:

public function __construct() {
while (\ob_get_level() > 0)
\ob_end_flush();
}

如此就可以得到即時的輸出資料了

2020年6月2日 星期二

[Linux] AddTrust External CA Root expired 處理方式 @ Ubuntu

週日也不幸踩到這個雷了,當時只解了幾個,沒想到這個範圍很大很大。
故事是我們採用 Namecheap 服務來簽署 Wildcard SSL 憑證,而使用到 AddTrust External CA Root 簽署。

當 AddTrust External CA Root 有效期間只到 2020/05/30 10:48:38 時,時間一到後,導致用戶連到我們的服務產生失敗,以 curl 來說,他預設依賴 OS 提供的系統憑證資訊:

$ curl https://ourservice.exmaple.com
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

而 Chrome Browser 很佛心,從軟體層自動幫轉到 USERTrust RSA Certification Authority。

問題的解法:

正確解法:直接再重新簽核新的憑證,新的憑證簽署時會略過已過期的項目。
臨時解法:將 https client side 的 AddTrust External CA Root 註解起來 

臨時解法,以 Ubuntu 內的 https client 為例,將 mozilla/AddTrust_External_Root.crt 那行註解起來

$ sudo vim /etc/ca-certificates.conf && sudo sh -c 'apt update && apt install ca-certificates && update-ca-certificates -f -v'

臨時解法只能解決 https client 是已知的範圍,像是服務的 client 都是自己控制的,這時就可以先解決那些 client 憑證的檢驗機制,但追到更細時,大部分的 https client 靠 OS 提供的憑證資訊就只要改一次,如果 https client 上跑 node.js 等應用,他們可能會依賴其他相關套件來維護憑證資訊,不一定會用 OS 內紀錄的憑證資訊,這時要排除會非常痛苦。因此,正確解法是重新簽發憑證