Computaria 讓我困擾的一件事是無法追蹤部落格本身的部署。那麼,既然這讓我煩惱,為什麼不解決它呢?
目前有兩種方法可以知道部署是否正在運行:
這兩個解決方案對我來說似乎都不太好。我想要計算本身更輕鬆的東西。
與 Kauê 短暫協商後,我決定遵循他的提示:在 /about 上發文。
在第一個實驗:
不,它變得醜陋了。我已經知道我不希望它預設出現。但帶上資訊就夠了。我只需要隱藏醜陋的東西,並在明確要求的情況下使其可用,即使是醜陋的。
嗯,首先要做的是知道我們是否應該採取任何行動。為此,將查詢參數 status 的值為 true 的存在定義為 API。
為了取得 URL,我使用了 window.location。 Location 物件內部有一個搜尋字段,它精確地用於維護用於存取特定 URL 的查詢參數。
例如,對於 http://localhost:4000/blog/about?q=1,window.location.search 的值為 ?q=1。為了更容易處理查詢參數中的內容,有一個 URLSearchParams 類型的物件。據我從文件中可以理解,要實例化 URLSearchParams,我需要查詢字串,但沒有 ?的前綴。我可以使用 window.location.search.substring(1).
來實現這一點現在,有了這個對象,我可以簡單地查詢我想要的任何查詢參數的值:
const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") }
有了這個,我需要採取顯示管道徽章的操作。為了方便起見,我決定將其作為可包含的 HTML 片段:_includes/pipeline.html。因此,我可以按照我認為合適的方式操作免費的 HTML。
一開始,它只是一個
<div> <p>Para importar, no /about só precisei colocar {%include pipeline.html%} no começo do arquivo, o Jekyll se encarregou de montar tudo certo.</p> <p>Ok, vamos por o script para detectar se deveria ou não exibir a tag:<br> </p> <pre class="brush:php;toolbar:false"><script> const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") } </script> <div> <p>So far, so good. Agora, vamos mudar a exibição para display: block caso seja para exibir o pipeline, ou sumir logo de uma vez com a <div>. Pelo console da web, bastaria fazer algo nesse esquema:<br> <pre class="brush:php;toolbar:false">const pipeline = document.getElementById("pipeline") if (...) { pipeline.style.display = "block" } else { pipeline.remove() }
放置在 HTML 片段:
<script> const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() } </script> <div> <p>E... falhou. Por quê? Porque no momento que a função rodar ainda não tem definido quem é o elemento com id pipeline. Então preciso mudar o ciclo de vida para rodar o script apenas quando a página for carregada. Basta colocar o <script defer>, certo? Bem, não. Porque defer não funciona bem com inline, apenas com arquivo de source explícito. Veja a documentação. <p>Ou seja, precisei colocar o arquivo JavaScript explicitamente para o Computaria. Como a priori tudo que está solto na pasta do blog é colocado como asset disponível para o Jekyll publicar, criei o js/pipeline-loader.js:<br> </p> <pre class="brush:php;toolbar:false"><script src="{{ "/js/pipeline-loader.js" | prepend: site.baseurl }}" defer> </script> <div> <p>E no script:<br> </p> <pre class="brush:php;toolbar:false">const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() }
太好了,讓我們做一些有用的事情並發布圖片?要動態建立元素,只需使用 document.createElement 即可。然後我輸入徽章網址:
const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" const pipelineImg = document.createElement("img") pipelineImg.src = "{{site.repository.base}}/badges/master/pipeline.svg" pipeline.appendChild(pipelineImg) } else { pipeline.remove() }
但是它顯示了一個破碎的圖像...嗯,控制台上顯示的訊息是什麼?
GET http://localhost:4000/blog/about/{{site.repository.base}}/badges/master/pipeline.svg [HTTP/1.1 404 Not Found 4ms]
奇怪,他應該得到了可愛的儲存庫 URL 嗎?哦,我注意到了。他根本沒有處理Liquid。為了解決這個問題,我決定遵循 css/main.scss 中的範例,一個空的 frontmatter。
const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") }
這會給出錯誤訊息,因為 frontmatter 不是 javascript,並且錯誤顯示在第一個 const 中。由於這讓我很困擾,我想到的最直接的處理方法就是儘早創建一個「無害的錯誤」。我加了一個 ;緊接在前言之後:
<div> <p>Para importar, no /about só precisei colocar {%include pipeline.html%} no começo do arquivo, o Jekyll se encarregou de montar tudo certo.</p> <p>Ok, vamos por o script para detectar se deveria ou não exibir a tag:<br> </p> <pre class="brush:php;toolbar:false"><script> const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") } </script> <div> <p>So far, so good. Agora, vamos mudar a exibição para display: block caso seja para exibir o pipeline, ou sumir logo de uma vez com a <div>. Pelo console da web, bastaria fazer algo nesse esquema:<br> <pre class="brush:php;toolbar:false">const pipeline = document.getElementById("pipeline") if (...) { pipeline.style.display = "block" } else { pipeline.remove() }
當我繼續測試時,我注意到網路標籤中不斷出現308,但為什麼會出現?嗯,因為展開 Liquid 時,它最終在徽章前出現了一個雙條。
我最初得到的是這個:
重新導向至:
當我分析我是否使用快取時,這開始困擾我。為了解決這個問題,我應該去掉雙斜線。我可以透過不在 Liquid 值展開後放置斜線來擺脫它,因為畢竟我可以先驗地知道 {{site.repository.base}} 字串以 / 結尾。但是,為了以防萬一,將斜線放在 /badges/master/pipeline.svg 之前實際上並沒有什麼壞處,它甚至是我作為讀者的一個指標。
但是,由於我不想依賴先驗知識來判斷此欄是否存在,因此我有兩個選擇:
JavaScript 方面對我來說似乎比較容易。所以只需將/替換為/,對嗎?嗯,不。由於協議出現在 :// 之前,因此僅進行粗略替換就會導致 url 開頭如下:https://computaria.gitlab.io。為了解決這個問題,我進行了以下替換:
<script> const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() } </script> <div> <p>E... falhou. Por quê? Porque no momento que a função rodar ainda não tem definido quem é o elemento com id pipeline. Então preciso mudar o ciclo de vida para rodar o script apenas quando a página for carregada. Basta colocar o <script defer>, certo? Bem, não. Porque defer não funciona bem com inline, apenas com arquivo de source explícito. Veja a documentação. <p>Ou seja, precisei colocar o arquivo JavaScript explicitamente para o Computaria. Como a priori tudo que está solto na pasta do blog é colocado como asset disponível para o Jekyll publicar, criei o js/pipeline-loader.js:<br> </p> <pre class="brush:php;toolbar:false"><script src="{{ "/js/pipeline-loader.js" | prepend: site.baseurl }}" defer> </script> <div> <p>E no script:<br> </p> <pre class="brush:php;toolbar:false">const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() }
分解:
透過此更改,https:// 不再具有match 與([^:])//,但路徑中// 的所有其他出現都具有完美匹配,因為它們不會前面一個:.更嚴格地說,我可以努力防止匹配在查詢參數/片段中發生,但這似乎太過分了。
好的,定義了放置位置和鎖定機制的詳細資訊後,我們需要一個重新載入機制。第一次嘗試:簡單地建立一個新的圖像元素。但還是這樣,怎麼辦?理想的情況是「一段時間後」。所以這給了我兩個選擇,可以說:
好吧,我們來看看它有什麼作用? setTimeout 接收一個命令,該命令將在一段時間間隔以及給定的時間間隔後執行。它會傳回一個 ID,您可以使用clearTimeout 將其刪除。如需重複調用,需要在最後再次調用setTimeout。
setInterval 幾乎是同樣的事情,只是它總是在時間間隔之後執行指令。傳回值應該是 ID,您可以呼叫clearInterval 來刪除它,但根據文檔,它也可以與clearTimeout 一起使用(以防萬一,不要相信它,請使用具有正確語義的 ID)。
我們應該使用 setTimeout 來建立一個循環呼叫嗎?在文字欄位中列印「南瓜」一詞 5 次怎麼樣?我將為這個實驗放置一個文字區域:
const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") }
好的,我想透過 HTML 存取 3 個函數。他們分裂(即使是非常輕微的)一個國家。我很喜歡隱藏東西,所以我不希望這種狀態在 <script> 標籤之外可見。 </script>
我最明顯的解決方案是將其放在一個區塊下,因此,當離開該區塊時,裡面的變數將在外面不可見:
<div> <p>Para importar, no /about só precisei colocar {%include pipeline.html%} no começo do arquivo, o Jekyll se encarregou de montar tudo certo.</p> <p>Ok, vamos por o script para detectar se deveria ou não exibir a tag:<br> </p> <pre class="brush:php;toolbar:false"><script> const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") } </script> <div> <p>So far, so good. Agora, vamos mudar a exibição para display: block caso seja para exibir o pipeline, ou sumir logo de uma vez com a <div>. Pelo console da web, bastaria fazer algo nesse esquema:<br> <pre class="brush:php;toolbar:false">const pipeline = document.getElementById("pipeline") if (...) { pipeline.style.display = "block" } else { pipeline.remove() }
好的,但是如何讓函數可見呢?好吧,經過實驗,我找到了一個方法:函數轉義作用域。由於局部變數沒有超出區塊的限制,我仍然可以在區塊內部放置一些輔助函數,這樣它們在外部就沒有任何意義。像這樣的東西:
<script> const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() } </script> <div> <p>E... falhou. Por quê? Porque no momento que a função rodar ainda não tem definido quem é o elemento com id pipeline. Então preciso mudar o ciclo de vida para rodar o script apenas quando a página for carregada. Basta colocar o <script defer>, certo? Bem, não. Porque defer não funciona bem com inline, apenas com arquivo de source explícito. Veja a documentação. <p>Ou seja, precisei colocar o arquivo JavaScript explicitamente para o Computaria. Como a priori tudo que está solto na pasta do blog é colocado como asset disponível para o Jekyll publicar, criei o js/pipeline-loader.js:<br> </p> <pre class="brush:php;toolbar:false"><script src="{{ "/js/pipeline-loader.js" | prepend: site.baseurl }}" defer> </script> <div> <p>E no script:<br> </p> <pre class="brush:php;toolbar:false">const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() }
好的,現在我需要處理超時呼叫。我的想法是執行一個步驟,當該步驟完成時,註冊下一個超時,調用相同的步驟。只是為了避免將此步驟永遠限制為幾次。
那麼,如果沒有超時問題,會是什麼樣子呢?遞歸呼叫:
const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" const pipelineImg = document.createElement("img") pipelineImg.src = "{{site.repository.base}}/badges/master/pipeline.svg" pipeline.appendChild(pipelineImg) } else { pipeline.remove() }
看起來不錯,加個超時怎麼樣?嗯,在步驟的主體內部,所以呼叫步驟就是設定逾時。為了一個好的暫停,我需要時間:
GET http://localhost:4000/blog/about/{{site.repository.base}}/badges/master/pipeline.svg [HTTP/1.1 404 Not Found 4ms]
好的,剩下要做的就是保存超時標識符,我們就準備好了。我將這一步放在公開的公共函數中,我們就準備好了:
--- # frontmatter vazio para fazer o parse do liquid --- const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" const pipelineImg = document.createElement("img") pipelineImg.src = "{{site.repository.base}}/badges/master/pipeline.svg" pipeline.appendChild(pipelineImg) } else { pipeline.remove() }
好的,我們現在有好玩的地方了:
見小提琴 https://jsfiddle.net/jeffque/5Lrasyqk/
setInterval 的使用非常相似,但「回想」步驟是隱含的。如果我想停止循環,我需要明確取消註冊的setInterval。
那麼,像上面的例子一樣開始怎麼樣?但有不同的暫存區 ID:
--- # frontmatter vazio para fazer o parse do liquid --- ; const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" const pipelineImg = document.createElement("img") pipelineImg.src = "{{site.repository.base}}/badges/master/pipeline.svg" pipeline.appendChild(pipelineImg) } else { pipeline.remove() }
見小提琴 https://jsfiddle.net/jeffque/5Lrasyqk/
定義了重複計時機制後,現在的問題是定義如何重新載入圖片。首先,分析 GitLab 在搜尋徽章時回傳的標頭:https://gitlab.com/computaria/blog//badges/master/pipeline.svg:
const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") }
比較來自不同請求的多個 etag,以防萬一:
<div> <p>Para importar, no /about só precisei colocar {%include pipeline.html%} no começo do arquivo, o Jekyll se encarregou de montar tudo certo.</p> <p>Ok, vamos por o script para detectar se deveria ou não exibir a tag:<br> </p> <pre class="brush:php;toolbar:false"><script> const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") } </script> <div> <p>So far, so good. Agora, vamos mudar a exibição para display: block caso seja para exibir o pipeline, ou sumir logo de uma vez com a <div>. Pelo console da web, bastaria fazer algo nesse esquema:<br> <pre class="brush:php;toolbar:false">const pipeline = document.getElementById("pipeline") if (...) { pipeline.style.display = "block" } else { pipeline.remove() }
嗯,etag 總是相同的,表明它是相同的資源。 cache-control: no-store 強烈告訴我它不是用來儲存快取的。指向過去的過期時間強烈表明它的目的是表明不應考慮對該資源進行快取。除非另有證明,cf-cache-status: MISS 僅表示它沒有命中 Cloudflare 的快取。
最後,嚴格的運輸安全。這意味著什麼?這和資源本身有什麼關係?
嗯,這與正在訪問的資源無關。但這表明該網站只能透過 HTTPS 存取。
好的,所有這些都表明圖像不應該是捲曲的。正如預期的那樣,F5 總是會導致它再次下載。對我來說,這是一個非常強大的指標,如果我的快取出現問題,它不會出現在伺服器或網路上,而是出現在瀏覽器層級。
第一次嘗試:建立一個新的 img 元素並丟掉先前的元素。
為了方便起見,沒有什麼比擁有一個傳回元素的函數更好的了:
<script> const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() } </script> <div> <p>E... falhou. Por quê? Porque no momento que a função rodar ainda não tem definido quem é o elemento com id pipeline. Então preciso mudar o ciclo de vida para rodar o script apenas quando a página for carregada. Basta colocar o <script defer>, certo? Bem, não. Porque defer não funciona bem com inline, apenas com arquivo de source explícito. Veja a documentação. <p>Ou seja, precisei colocar o arquivo JavaScript explicitamente para o Computaria. Como a priori tudo que está solto na pasta do blog é colocado como asset disponível para o Jekyll publicar, criei o js/pipeline-loader.js:<br> </p> <pre class="brush:php;toolbar:false"><script src="{{ "/js/pipeline-loader.js" | prepend: site.baseurl }}" defer> </script> <div> <p>E no script:<br> </p> <pre class="brush:php;toolbar:false">const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" } else { pipeline.remove() }
在 setTimeout 中,我需要刪除 #pipeline 子級並插入新映像。我透過父親的行動找到的選項是:
嗯,removeChild 和replaceChild 涉及了解如何保存舊元素以請求將其刪除。另一方面,ReplaceChildren 沒有任何戲劇性,它只是傳遞了新元素,這很好:
const queryParams = new URLSearchParams(window.location.search.substring(1)); const pipeline = document.getElementById("pipeline") if (queryParams.get("status") === "true") { pipeline.style.display = "block" const pipelineImg = document.createElement("img") pipelineImg.src = "{{site.repository.base}}/badges/master/pipeline.svg" pipeline.appendChild(pipelineImg) } else { pipeline.remove() }
僅此一點就產生了魔力。那麼,它的表現如何?
創建新的 img 還不夠。
我發現的另一個替代方法是再次設定變數值。這樣,就不再需要產生相同元素的函數,我只需「修改」img 指向的 URL 即可。而且,這就是我如何發現在同一頁上的多個位置使用相同資源可能會遭受某種快取的情況......
好吧,如果每次重複都在 URL 末尾添加一個「 」來嘗試欺騙 GitLab 會怎麼樣?好吧,gitlab 意識到我不懷好意...
如果它是一個帶有參數或其迭代器傳遞的查詢參數呢?
但是,代價是什麼?
好的,這不可能,因為這是一種解決方法,讓我們嘗試獲取它?然後給fetch之後,想想如何替換圖片?
const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") }
嗯,錯誤,來自 CORS。既然我無法控制 GitLab,我還能做什麼?
;沒有重新加載,但
好的,新實驗:簡單地使用 img 標籤建立 /assets/pipeline.html 並從 iframe 指向它。對於強制重新載入操作,我使用了與 Stack Overflow 答案相同的內容:
<div> <p>Para importar, no /about só precisei colocar {%include pipeline.html%} no começo do arquivo, o Jekyll se encarregou de montar tudo certo.</p> <p>Ok, vamos por o script para detectar se deveria ou não exibir a tag:<br> </p> <pre class="brush:php;toolbar:false"><script> const queryParams = new URLSearchParams(window.location.search.substring(1)); if (queryParams.get("status") === "true") { console.log("oba, vamos exibir o pipeline!") } else { console.log("nops, não vamos exibir nada") } </script> <div> <p>So far, so good. Agora, vamos mudar a exibição para display: block caso seja para exibir o pipeline, ou sumir logo de uma vez com a <div>. Pelo console da web, bastaria fazer algo nesse esquema:<br> <pre class="brush:php;toolbar:false">const pipeline = document.getElementById("pipeline") if (...) { pipeline.style.display = "block" } else { pipeline.remove() }
轉為 HTML
然後,去那裡!成功了!
現在,進行調整以使其適合:
透過進行這些調整,您可以擺脫困境
為此
您可以檢查這裡使用的檔案:
以上是使管道可見以監控部落格部署的詳細內容。更多資訊請關注PHP中文網其他相關文章!