<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Richard隨手筆記</title><link href="https://blog.richardnote.com/" rel="alternate"></link><link href="https://blog.richardnote.com/feeds/all.atom.xml" rel="self"></link><id>https://blog.richardnote.com/</id><updated>2023-05-15T12:07:00+08:00</updated><subtitle>紙上得來終覺淺，絕知此事要躬行</subtitle><entry><title>Azure Data Studio 套件安裝</title><link href="https://blog.richardnote.com/2023/05/Azure-Data-Studio-Vsix/" rel="alternate"></link><published>2023-05-15T12:07:00+08:00</published><updated>2023-05-15T12:07:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2023-05-15:/2023/05/Azure-Data-Studio-Vsix/</id><summary type="html">&lt;p&gt;Azure-Data-Studio&lt;/p&gt;</summary><content type="html">
&lt;p&gt;Azure Data Studio 是一個GUI介面，可以在不同的平臺上執行，可在Mac，Window，Linux不同平臺安裝，以下在Mac環境安裝時，發生的問題：&lt;/p&gt;
&lt;p&gt;在Mac安裝參考官方教學 ：&lt;a href="https://learn.microsoft.com/zh-tw/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16&amp;amp;tabs=redhat-install%2Credhat-uninstall"&gt;下載並安裝 Azure Data Studio&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;由於需要新增中文介面套件，在後來的擴充套件安裝時，發生了以下問題點&lt;/p&gt;
&lt;h3 id="_1"&gt;無法點擊安裝&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;installing&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Chinese&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Traditional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Language&lt;/span&gt; &lt;span class="n"&gt;Pack&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;Studio&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Please&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nl"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;workbench&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;showWindowLog&lt;/span&gt; &lt;span class="s"&gt;"Click to execute command 'workbench.action.showWindowLog'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上述的錯誤出現，想說查看原始 vsix檔案來安裝&lt;/p&gt;
&lt;p&gt;找到 https://github.com/microsoft/azuredatastudio/wiki/List-of-Extensions 原始的Github路徑&lt;/p&gt;
&lt;p&gt;![[ADS原始中文安裝包路徑.png]]&lt;/p&gt;
&lt;p&gt;接下來如下圖方式安裝：下面截圖是已經安裝完成的情況才顯示中文 ![[使用vsix方式安裝.png]]&lt;/p&gt;
&lt;h3 id="128"&gt;無法安裝套件在1.28版本上&lt;a class="headerlink" href="#128" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;實際上又出現如下的錯誤訊息&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Unable&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ads&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;zh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hant&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;compatible&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;Studio&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mf"&gt;1.28.0&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;由於當初安裝的Azure Data Studio版本已經過時，所以才造成上面的這些問題，再次從GitHub https://github.com/Microsoft/azuredatastudio  下載Mac M1 版本的檔案，如下圖，點擊 Apple Silicon 版本安裝&lt;/p&gt;
&lt;p&gt;![[下載MacM1版本的檔案ADS.png]]&lt;/p&gt;
&lt;p&gt;最後正確安裝顯示，並且版本顯示 1.43，上面的套件安裝問題就沒問題了 ![[AzureDataStudio2畫面.png]]&lt;/p&gt;</content><category term="電腦問題"></category><category term="Azure Data Studio"></category><category term="Language Packs"></category></entry><entry><title>分析工具－DebugDiag Tools</title><link href="https://blog.richardnote.com/2023/03/fen-xi-gong-ju-debugdiag-tools/" rel="alternate"></link><published>2023-03-14T16:41:00+08:00</published><updated>2023-03-14T16:41:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2023-03-14:/2023/03/fen-xi-gong-ju-debugdiag-tools/</id><summary type="html">&lt;p&gt;預覽標題&lt;/p&gt;</summary><content type="html">
&lt;h2 id="debugdiag-tools"&gt;此次針對專案的記憶體不足做優化，在此次的記憶體檢測使用DebugDiag Tools&lt;a class="headerlink" href="#debugdiag-tools" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DebugDiag Tools（Debug Diagnostic Tool）是一款由 Microsoft 提供的免費工具，用於幫助開發人員和 &lt;span class="caps"&gt;IT&lt;/span&gt; 專業人員在 Windows 系統上診斷和解決應用程式問題。該工具集提供了一組分析工具，可幫助您捕捉、分析和解決各種應用程式問題，例如記憶體洩漏、當機和性能問題等。&lt;/p&gt;
&lt;p&gt;DebugDiag 可以輕鬆捕捉和記錄應用程式當機時的詳細資訊，包括當機的位置和原因。它還提供了一組分析工具，可幫助您檢查記憶體使用情況，找出記憶體洩漏的原因。此外，DebugDiag 工具還可以監視應用程式的性能，並提供了一組分析工具，可幫助您找出應用程式性能問題的根本原因。&lt;/p&gt;
&lt;h3 id="_1"&gt;下載與安裝&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;下載點：&lt;a href="https://www.microsoft.com/en-us/download/details.aspx?id=58210"&gt;Debug Diagnostic Tool v2 Update 3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安裝完成如下會主要有兩個功能：
DebugDiag 2 Analysis   &amp;lt;- 這是用來分析的
DebugDiag 2 Collection &amp;lt;- 這是用來收集資料的&lt;/p&gt;
&lt;p&gt;![[DebugDiagnosticsTool2.jpg]]&lt;/p&gt;
&lt;h3 id="_2"&gt;針對記憶體的使用&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;因為主要需要探究記憶體不足，需要確認哪些程式佔用了大部分的記憶體使用先選擇Native(non-.Net)Memory and Handle Leak&lt;/p&gt;
&lt;p&gt;![[NativeMemoryandHandleLeak.jpg]]&lt;/p&gt;
&lt;p&gt;接下來切換視窗頁籤的Processes 查看要觀察的對象，在此次範例中，已經將程式建立在IIS上，在IIS的ProcessName是 w3wp.exe 後面的有個欄位Process Identiy 是設定在IIS上的名稱 ![[分析工具查看IIS上的記憶體使用進程.jpg]]&lt;/p&gt;
&lt;p&gt;接下來就可以狂打這個站臺來模擬使用大量呼叫時記憶體會衝多高，再針對此Process，按右鍵出現選單選擇 Create Full Userdump&lt;/p&gt;
&lt;p&gt;![[把觀察的進程資料Dump出來.jpg]]&lt;/p&gt;
&lt;p&gt;在Windows系統，此Dump出來的資料，會在預設路徑 C:\Program Files\DebugDiag\Logs\Misc&lt;/p&gt;
&lt;p&gt;在這個路徑會有副檔名是  .dmp  的檔案類型，接下來針對這個檔案，右鍵選擇DebugDiag 2 Analysis 來開啟分析，就會產生報告，報告路徑可以自定義，副檔名為 mht ，似乎只能使用舊IE來開啟才能看 ![[把dump出來的檔案右鍵使用分析工具開啟.jpg]]&lt;/p&gt;
&lt;p&gt;![[佔用的記憶體前幾大項目.png]]&lt;/p&gt;
&lt;p&gt;在 C# 中，由於 String 物件是不可變的，因此在進行字串操作時，每當需要更改 String 物件時，都會建立新的 String 物件。這種方式可能會導致大量的記憶體使用，特別是當處理大量文字時。&lt;/p&gt;
&lt;p&gt;以下是一些優化 C# 程式時使用 String 物件的方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;使用 StringBuilder：StringBuilder 是可變的字串類別，它提供了可變長度的字串，因此在字串操作時使用 StringBuilder 可以避免建立大量的 String 物件，以減少記憶體使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 String.Concat：在需要連接多個字串時，使用 String.Concat 方法可以將多個字串連接為一個字串，而不必建立中間字串物件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用格式化字串：在需要產生複雜字串時，使用格式化字串可以更容易地產生複雜字串。在格式化字串中，可以使用佔位符來代表變數，然後在執行時將變數插入到字串中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;避免使用 + 運算子連接字串：在使用 + 運算子連接字串時，每次操作都會建立新的 String 物件，這樣可能會導致大量的記憶體使用。因此，在需要連接多個字串時，應該使用 StringBuilder 或 String.Concat 方法來連接字串。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;避免在迴圈中連接字串：在迴圈中連接字串可能會導致大量的記憶體使用。因此，在需要在迴圈中連接字串時，應該使用 StringBuilder 或類似的方法來減少記憶體使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;了解字串比較的運作方式：當進行字串比較時，可以使用 StringComparison 列舉來指定比較的方式。例如，使用 StringComparison.Ordinal 可以比較字串的 &lt;span class="caps"&gt;ASCII&lt;/span&gt; 編碼值，這種比較方式比使用預設的比較方式更快。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;綜上所述，使用 StringBuilder 和 String.Concat 可以有效地減少記憶體使用，並在需要產生複雜字串時使用格式化字串，避免在迴圈中連接字串。另外，了解字串比較的運作方式也可以幫助優化程式。&lt;/p&gt;
&lt;p&gt;參考資料:
https://blog.darkthread.net/blog/windbg-to-find-aspnet-cpu-high/
https://blog.darkthread.net/blog/analyze-cpu-high-with-debugdiag-tools
&lt;a href="https://support.microsoft.com/zh-tw/topic/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-debug-diagnostics-tool-%E5%9C%A8-iis-%E4%B8%AD%E7%82%BA-cpu-%E4%BD%BF%E7%94%A8%E7%8E%87%E9%81%8E%E9%AB%98%E7%9A%84%E8%99%95%E7%90%86%E5%BA%8F%E9%80%B2%E8%A1%8C%E7%96%91%E9%9B%A3%E6%8E%92%E8%A7%A3-636559d3-2f31-71eb-d2ba-75da26ece9d7"&gt;如何使用 Debug Diagnostics Tool，在 &lt;span class="caps"&gt;IIS&lt;/span&gt; 中為 &lt;span class="caps"&gt;CPU&lt;/span&gt; 使用率過高的處理序進行疑難排解&lt;/a&gt;&lt;/p&gt;</content><category term="電腦問題"></category><category term="標籤"></category></entry><entry><title>Nginx 在MacOS M1問題</title><link href="https://blog.richardnote.com/2022/12/nginx-macos-error/" rel="alternate"></link><published>2022-12-07T21:45:00+08:00</published><updated>2022-12-07T21:45:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-12-07:/2022/12/nginx-macos-error/</id><summary type="html">&lt;p&gt;Nginx 在MacOS&amp;nbsp;M1問題&lt;/p&gt;</summary><content type="html">&lt;p&gt;[&lt;span class="caps"&gt;TOC&lt;/span&gt;]
設定修改nginx 然後需要reload 出現 &lt;code&gt;PID number "" in "/opt/homebrew/var/run/nginx.pid"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看檔案是空的，刪掉又出現另外一個問題&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="nv"&gt;@zhengrungdeMini&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="nl"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;invalid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;/opt/homebrew/var/run/nginx.pid&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;刪掉後出現：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="nv"&gt;@zhengrungdeMini&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="nl"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;/opt/homebrew/var/run/nginx.pid&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;such&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;看起來這個檔案需要點東西。但是卻沒有東西需要重新產生&lt;/p&gt;
&lt;p&gt;參考資料&amp;nbsp;https://ld246.com/article/1563147639170&lt;/p&gt;
&lt;p&gt;後來執行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;sudo nginx -c /opt/homebrew/etc/nginx/nginx.conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;上面語法 要先找到原本nginx的設定的原始路徑 然後依照上面這個語法就會產生在/opt/homebrew/var/run/nginx.pid&amp;nbsp;產生完成就會出現內容有數字&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;sudo certbot --expand -d jupyter.richardrobot.xyz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Saving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;letsencrypt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;letsencrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;Could&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssl_module&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;disabling&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;session&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tickets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="nl"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;emerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;/usr/local/etc/nginx/nginx.conf&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;such&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="nl"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;以上的問題是因為MacOS的M1安裝Nginx預設路徑已經是 /opt/homebrew/etc/nginx ，但是在設定certbot
的時候會用預設以前的路徑/usr/local/etc/nginx/nginx.conf&amp;nbsp;，所以必須指定路徑&lt;/p&gt;
&lt;p&gt;用以下語法自定義路徑&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;certbot --nginx --nginx-server-root=/opt/homebrew/etc/nginx/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="電腦問題"></category><category term="nginx"></category><category term="mac"></category></entry><entry><title>MacOS下的Terminal語法</title><link href="https://blog.richardnote.com/2022/12/macos-terminal-command/" rel="alternate"></link><published>2022-12-07T21:41:00+08:00</published><updated>2022-12-07T21:41:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-12-07:/2022/12/macos-terminal-command/</id><summary type="html">&lt;p&gt;記錄terminal語法以備不時之需&lt;/p&gt;</summary><content type="html">&lt;p&gt;[&lt;span class="caps"&gt;TOC&lt;/span&gt;]&amp;nbsp;查看電腦的對外IP：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;curl ifconfig.me&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;查看TCP端口與查看監聽端口：把 $&lt;span class="caps"&gt;PORT&lt;/span&gt;&amp;nbsp;換成要查看的PORT&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;sudo lsof -i -P | grep LISTEN | grep :$PORT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;使用SSH連線：本地端使用443轉出去再連線&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;ssh -p443 jarvis.zheng@remoteIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Netstat&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="n"&gt;顯示傳輸協定統計和當前的&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;網路連接&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="n"&gt;該指令只有在安裝了&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;傳輸協定後才可以使用&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="n"&gt;netstat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-e&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-n&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-p protocol&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;-r&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="n"&gt;參數&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;顯示所有連接和偵聽連接阜&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="n"&gt;伺服器連接通常不顯示&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;顯示乙太網統計&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="n"&gt;該參數可以與&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;選項結合使用&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;以數位格式顯示位址和連接阜號&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;而不是嘗試搜尋名稱&lt;/span&gt;&lt;span class="err"&gt;）。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;顯示每個傳輸協定的統計&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="n"&gt;預設情況下&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;顯示&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;UDP&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;ICMP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;和&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;的統計&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;選項可以用來指定預設的子集&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;顯示由&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;指定的傳輸協定的連接&lt;/span&gt;&lt;span class="err"&gt;；&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;可以是&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;或&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;udp&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="n"&gt;如果與&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;選項一同使用顯示每個傳輸協定的統計&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;可以是&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;udp&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;或&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;顯示路由表的內容&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="k"&gt;interval&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="n"&gt;重新顯示所選的統計&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;在每次顯示之間暫停&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;interval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;秒&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="電腦問題"></category><category term="mac"></category><category term="terminal"></category></entry><entry><title>依賴注入的心得筆記</title><link href="https://blog.richardnote.com/2022/09/ioc-di/" rel="alternate"></link><published>2022-09-05T19:46:00+08:00</published><updated>2022-09-05T19:46:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-09-05:/2022/09/ioc-di/</id><summary type="html">&lt;p&gt;依賴注入的心得筆記&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;依賴注入的入門階段&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;自從被打槍不會ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 後，就不斷的學習新的NetCore技術，先後買了幾本書，&lt;/p&gt;
&lt;p&gt;第一本：&lt;a href="https://www.tenlong.com.tw/products/9789865501402?list_name=srh"&gt;完全精通微軟Web架構: &lt;span class="caps"&gt;ASP&lt;/span&gt;.Net Core 3最新強實戰&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;說實在的，這本書似乎不太適合我看，首先對於兩岸的文字描述，對我來講實在有點障礙，在專有名詞上，我還是偏好非中國那邊的用語，另外這本的講解，讓我覺得文字說明不夠簡單扼要，常常看了一個段落，然後實在看不明白到底要表達什麼，看過另外一本的依賴注入後才發覺這本書文字的累贅，不過其實還是不錯的書，至少把NetCore的最根本原理與NetCore如何實現跨平台與各個Middleware說明的很徹底，還是值得的一本，只不過我要看很久。&lt;/p&gt;
&lt;p&gt;第二本：&lt;a href="https://www.tenlong.com.tw/products/9789864344987?list_name=srh"&gt;依賴注入：原理、實作與設計模式 (Dependency Injection: Principles, Practices, Patterns, 2/e)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這本在看了上面第一本ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 3 後，發現依賴注入是ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 核心概念，並且第一本的依賴注入講解的內容我覺得實在不懂，後來又買了這本。 著實的認為這本真的是非常好的書，&lt;/p&gt;
&lt;h2 id="_2"&gt;依賴注入的概念假想&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;說道依賴注入，書上用插座的範例來說明設計模式的譬喻，來讓讀者能夠深刻體會設計模式是如何實現的。不免俗的我自己也有自己一套譬喻假想，常常人家說到依賴注入就會說到 IoC (控制反轉)，然後就是依賴注入的 組合根，建構子注入，屬性注入，方法注入，DI容器，光是這麼多名詞，硬記也不知道在記什麼，但是讀到後面卻產生一個很相似的譬喻：{『武林的世界』&lt;/p&gt;
&lt;p&gt;首先，要成為一個武林高手，必須內外兼修，內就是修煉內功心法，外就是修煉武學招式，
對於依賴注入，IoC控制反轉就感覺是修煉內功心法，為何如此說法呢？先看看名詞定義，以下引用&lt;a href="https://www.tenlong.com.tw/products/9789865501402?list_name=srh"&gt;完全精通微軟Web架構: &lt;span class="caps"&gt;ASP&lt;/span&gt;.Net Core 3最新強實戰&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="inverse-of-control"&gt;控制反轉（Inverse of Control）&lt;a class="headerlink" href="#inverse-of-control" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;對於任何一項工作，不論大小，基本上都可以分解成對應的步驟，所以任何一項工作的實施都有固定的流程，而IoC的控制就是視作『&lt;strong&gt;&lt;em&gt;針對流程的控制&lt;/em&gt;&lt;/strong&gt;』。一般來講，設計模式是為了解決一個實際問題的方案，但是IoC沒有一個針對性的問題領域，本身也沒有提供一種可操作的解決方案，所以認為視為IoC是一種『&lt;strong&gt;&lt;em&gt;設計原則&lt;/em&gt;&lt;/strong&gt;』&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由以上的定義可以瞭解，控制反轉是一個概念，一個設計原則，當我們在定義介面的時候，對於功能的切割是由哪些類別來注入，實際的控制權是由外部注入的，所以『&lt;strong&gt;&lt;em&gt;針對流程的控制&lt;/em&gt;&lt;/strong&gt;』要如何定義的靈活與彈性就要靠日後的練習，完全就是一個心法的概念。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="_3"&gt;什麼是『組合根』&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;可以組合應用程式中使用的類別。 將需要實體物件的建立作業，全部集中化到一個地方，而這個負責處理作業的區塊就是『組合根』，通常是應用程式的啟動點，在NetCore就是Main方法中。&lt;/p&gt;
&lt;h3 id="_4"&gt;建構子注入&lt;a class="headerlink" href="#_4" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;必須在Public 修飾子的建構子中以建構子參數的形式，定義這份依賴需求，要求外部提供物件。 重要：建構子參數要增加必須在同一個建構子增加額外的參數，避免使用多載方式導致混淆。&lt;/p&gt;
&lt;h3 id="_5"&gt;屬性注入&lt;a class="headerlink" href="#_5" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;接著讓我們來看看屬性注入，顧名思義就是&lt;strong&gt;從公開的屬性丟進去&lt;/strong&gt;，因此有時候也會被叫做設值注入。
通常我們會在 &lt;strong&gt;「外部使用者要能夠隨時切換依賴對象」或是「類別已經有預設值了，但希望提供使用者可以覆寫掉預設值的彈性」時用到屬性注入&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="_6"&gt;方法注入&lt;a class="headerlink" href="#_6" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;當依賴對象可能會隨著每次呼叫的方法不同，又或者是依賴對象不變但每次的使用方都有可能變化時，就需要透過方法參數的形式來設定依賴關係。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上述這些定義就是依賴注入的方法，組合根就是在定義如何引用各個類別，組合起所有的類別，這些方式就是類似拳腳基本功，有了基本的拳腳功夫，接下來就是討論到DI容器，DI容器可以說是各個門派的獨有的技能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h3 id="di"&gt;DI容器技術&lt;a class="headerlink" href="#di" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;所謂的DI容器技術指的就是一套軟體函式庫，協助我們將許多包括『物件關聯組合』，『管理物件生命週期』等作業自動化。&lt;/p&gt;
&lt;p&gt;由上述的定義可瞭解到，使用依賴注入，會有許多相關的知識需要理解，在此不多講解，可參考
&lt;a href="https://www.tenlong.com.tw/products/9789864344987?list_name=srh"&gt;依賴注入：原理、實作與設計模式 (Dependency Injection: Principles, Practices, Patterns, 2/e)&lt;/a&gt;&lt;br/&gt; 第七章到第九章的內容&lt;/p&gt;
&lt;p&gt;然而DI容器其實是協助我們管理跟自動化，而提供許多的函式方法來協助我們，下面就會記錄與說明函式的方法。讓我們加入華山派的劍宗吧。&lt;/p&gt;
&lt;h2 id="autofac"&gt;依賴注入的容器：Autofac的記錄&lt;a class="headerlink" href="#autofac" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://autofac.org/apidoc/html/62C594FF.htm"&gt;Autofac .&lt;span class="caps"&gt;NET&lt;/span&gt; Inversion of Control Container&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContainerBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;domainAssembly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITimeProvider&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DefaultTimeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITimeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="n"&gt;SingleInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IUserContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AspNetUserContextAdapter&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CommerceContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InstancePerLifetimeScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domainAssembly&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;AsClosedTypesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuditingCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SaveChangesCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SecureCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// ---- Start code section 13.4.4 ----&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domainAssembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetInterfaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsClosedTypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
            &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;KeyedService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGeneric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompositeEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResolveNamed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParameterType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="c1"&gt;// ---- End code section 13.4.4 ----&lt;/span&gt;

    &lt;span class="c1"&gt;// Register adapters to external systems&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WcfBillingSystem&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Register repositories&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SqlProductRepository&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Repository"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class="caps"&gt;TODO&lt;/span&gt;：等待學習中….
RegisterType
RegisterInstance
RegisterAssemblyTypes RegisterGenericDecorator&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ithelp.ithome.com.tw/users/20144614/ironman/5120"&gt;[Dot Net Core](圖解系列與常用套件)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://autofac.readthedocs.io/en/latest/index.html"&gt;官方文檔&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Dependency Injection"></category></entry><entry><title>GIT錯誤：the remote end hung up unexpectedly</title><link href="https://blog.richardnote.com/2022/07/git-remote-hung-up-unexpectedly/" rel="alternate"></link><published>2022-07-28T17:20:00+08:00</published><updated>2022-07-28T17:20:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-07-28:/2022/07/git-remote-hung-up-unexpectedly/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;GIT&lt;/span&gt; error：the remote end hung up&amp;nbsp;unexpectedly&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;最近修改專案，新增了許多packages，然後加入Git 清單內，但是當要PUSH時，就發生如下錯誤訊息，&amp;nbsp;git小烏龜報錯如標題&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;Enumerating objects: 490, done.&lt;/span&gt;
&lt;span class="err"&gt;Counting objects: 100% (381/381), done.&lt;/span&gt;
&lt;span class="err"&gt;Delta compression using up to 12 threads&lt;/span&gt;
&lt;span class="err"&gt;Compressing objects: 100% (288/288), done.&lt;/span&gt;
&lt;span class="c"&gt;error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400&lt;/span&gt;
&lt;span class="c"&gt;fatal: the remote end hung up unexpectedly&lt;/span&gt;
&lt;span class="err"&gt;Writing objects: 100% (299/299), 7.85 MiB | 8.89 MiB/s, done.&lt;/span&gt;
&lt;span class="err"&gt;Total 299 (delta 133), reused 16 (delta 1), pack-reused 0&lt;/span&gt;
&lt;span class="c"&gt;fatal: the remote end hung up unexpectedly&lt;/span&gt;
&lt;span class="err"&gt;Everything up-to-date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;查詢google後，約略可能為如下原因所引發的，git上傳實際會將先檔案放入緩衝區，緩衝區如果設置的值比要上傳的內容小，那麼就會出現這個錯誤&lt;/p&gt;
&lt;p&gt;修改提交緩存區大小為5GB，或者更大的數字，該方式全域生效，一勞永逸&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config --global http.postBuffer 5242880000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;參考資料：&lt;a href="https://www.cnblogs.com/rgqjson/p/13297526.html"&gt;git 推送出现 &amp;#8220;fatal: The remote end hung up unexpectedly&amp;#8221;&amp;nbsp;解决方案&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="git"></category></entry><entry><title>IIS問題-500.19</title><link href="https://blog.richardnote.com/2022/07/URLRewrite/" rel="alternate"></link><published>2022-07-19T13:53:00+08:00</published><updated>2022-07-19T13:53:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-07-19:/2022/07/URLRewrite/</id><summary type="html">&lt;p&gt;URLRewrite與IIS設定問題&lt;/p&gt;</summary><content type="html">
&lt;p&gt;本機發佈程式到IIS會出現 500.19錯誤，緣由是因為URLRewrite的在站臺的Web.Config設定錯誤，導致此問題發生。並且記錄當初處理的情況流程。&lt;/p&gt;
&lt;p&gt;錯誤畫面： ![[IIS上WebConfig錯誤50019.png]]&lt;/p&gt;
&lt;p&gt;看起來上面的錯誤是因為下面這兩個設定造成的，我只要把下面這兩個設定去除，IIS就可以用了，所以似乎是因為IIS原本的模組就已經有關於這兩個資料夾目錄隱藏的設定，但是現在又在Web.config裡面又在次設定了一次，所以可能出錯的原因是這個&lt;/p&gt;
&lt;p&gt;![[PCAdmin的WebConfig設定.png]]
![[system32的config設定.png]]
把站臺的WebConfig設定的App_Data 、Bin 的那兩個東西拿掉就OK了，但是這似乎不是解決的真正，因為這樣修改，把IIS所有關於安全性隱藏資料夾的問題給顯現出來了，變成只有DevPCAdmin專案才回隱藏這兩個資料夾，其他反而凸顯出問題&lt;/p&gt;
&lt;h3 id="url-rewrite-20"&gt;重點是站臺有裝 &lt;span class="caps"&gt;URL&lt;/span&gt; Rewrite 2.0：&lt;a class="headerlink" href="#url-rewrite-20" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;rewrite&gt; &lt;/rewrite&gt;&lt;/p&gt;
&lt;p&gt;&lt;outboundrules&gt; &lt;/outboundrules&gt;&lt;/p&gt;
&lt;p&gt;&lt;rule name="Remove Server"&gt; &lt;/rule&gt;&lt;/p&gt;
&lt;p&gt;&lt;match pattern=".+" servervariable="RESPONSE_SERVER"&gt;&lt;/match&gt; &lt;/p&gt;
&lt;p&gt;&lt;action type="Rewrite" value="Apache/2.4.12 (Unix) OpenSSL/1.0.2a PHP/5.6.0"&gt;&lt;/action&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;rewrite&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;outboundRules&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;rule&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Remove Server"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;match&lt;/span&gt; &lt;span class="na"&gt;serverVariable=&lt;/span&gt;&lt;span class="s"&gt;"RESPONSE_SERVER"&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;".+"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"Rewrite"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Apache/2.4.12 (Unix) OpenSSL/1.0.2a PHP/5.6.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/rule&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/outboundRules&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/rewrite&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;拿掉這個的時候就好了，所以是IIS要新裝這個功能才可以&lt;/p&gt;
&lt;p&gt;![[安裝URLReWrite.jpg]]&lt;/p&gt;
&lt;p&gt;多年後又出現一樣的問題，在重新發佈之後出現一樣問題，但是在IIS上已經安裝此功能&lt;/p&gt;
&lt;p&gt;![[WebPlatformInstaller安裝項目.png]]&lt;/p&gt;
&lt;p&gt;解決：一開始就設定錯誤，預設的隱藏標籤本來就包含下列，所以必定會造成錯誤，查看PROD設定卻沒有這個設定，原來在一開始就在本機的設定是錯誤的了&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;hiddenSegments&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;segment=&lt;/span&gt;&lt;span class="s"&gt;"App_Data"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;segment=&lt;/span&gt;&lt;span class="s"&gt;"bin"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/hiddenSegments&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="網路概論"></category><category term="URLRewrite"></category><category term="IIS"></category></entry><entry><title>反向代理</title><link href="https://blog.richardnote.com/2022/03/reverse-proxy/" rel="alternate"></link><published>2022-03-29T20:00:00+08:00</published><updated>2022-03-29T20:00:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-03-29:/2022/03/reverse-proxy/</id><summary type="html">&lt;p&gt;瞭解反向代理與正向代理&lt;/p&gt;</summary><content type="html">
&lt;p&gt;在瞭解反向代理之前，先瞭解正向代理，&lt;/p&gt;
&lt;p&gt;正向代理（forward proxy）：是一個位於客戶端和目標伺服器之間的伺服器(代理伺服器)，為了從目標伺服器取得內容，客戶端向代理伺服器發送一個請求並指定目標，然後代理伺服器向目標伺服器轉交請求並將獲得的內容返回給客戶端。&lt;/p&gt;
&lt;p&gt;![[正向代理伺服器.jpg]]&lt;/p&gt;
&lt;p&gt;正向代理伺服器用途：
- 突破訪問限制
- 提高訪問速度
- 隱藏客戶端真實IP&lt;/p&gt;
&lt;p&gt;反向代理（reverse proxy）：是指以代理伺服器來接受internet上的連接請求，然後將請求轉發給內部網絡上的伺服器，並將從伺服器上得到的結果返回給internet上請求連接的客戶端，此時代理伺服器對外就表現為一個反向代理伺服器。  &lt;/p&gt;
&lt;p&gt;![[反向代理.jpg]]&lt;/p&gt;
&lt;p&gt;反向代理的用途：
- 隱藏伺服器真實IP
- 負載平衡
- 提高訪問速度
- 提供安全保障&lt;/p&gt;
&lt;h4 id="_1"&gt;&lt;strong&gt;正向代理和反向代理的區別&lt;/strong&gt;&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;雖然正向代理伺服器和反向代理伺服器所處的位置都是客戶端和真實伺服器之間，所做的事情也都是把客戶端的請求轉發給伺服器，再把伺服器的響應轉發給客戶端，但是二者之間還是有一定的差異的。&lt;/p&gt;
&lt;p&gt;1、&lt;em&gt;正向代理其實是客戶端的代理&lt;/em&gt;，幫助客戶端訪問其無法訪問的伺服器資源。&lt;em&gt;反向代理則是伺服器的代理&lt;/em&gt;，幫助伺服器做負載均衡，安全防護等。&lt;/p&gt;
&lt;p&gt;2、&lt;em&gt;正向代理一般是客戶端架設的&lt;/em&gt;，比如在自己的機器上安裝一個代理軟體。而&lt;em&gt;反向代理一般是伺服器架設的&lt;/em&gt;，比如在自己的機器集群中部署一個反向代理伺服器。&lt;/p&gt;
&lt;p&gt;3、&lt;em&gt;正向代理中，伺服器不知道真正的客戶端到底是誰&lt;/em&gt;，以為訪問自己的就是真實的客戶端。而在&lt;em&gt;反向代理中，客戶端不知道真正的伺服器是誰&lt;/em&gt;，以為自己訪問的就是真實的伺服器。&lt;/p&gt;
&lt;p&gt;4、正向代理和反向代理的作用和目的不同。&lt;em&gt;正向代理主要是用來解決訪問限制問題。而反向代理則是提供負載均衡、安全防護等作用。二者均能提高訪問速度。&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;結論：簡單講，正向代理就是使用者這段的，相反的，反向代理就是伺服器這段的 代理不同，正向代理是使用者，反向代理是真實伺服器&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kknews.cc/zh-tw/tech/k66p2gb.html"&gt;終於有人把正向代理和反向代理解釋的明明白白了&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.oracle.com/cd/E19438-01/819-3163/agfltr.html"&gt;透過代理伺服器篩選內容&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="反向代理"></category></entry><entry><title>使用Automator定期執行Blog發佈</title><link href="https://blog.richardnote.com/2022/01/mac-automator-blog/" rel="alternate"></link><published>2022-01-14T17:40:00+08:00</published><updated>2022-01-14T17:40:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-14:/2022/01/mac-automator-blog/</id><summary type="html">&lt;p&gt;加強Blog發佈程式流程&lt;/p&gt;</summary><content type="html">
&lt;p&gt;之前寫的同步方式：[[Obsidian筆記同步到Blog排程]]，還是很多地方不完善，每次都需要手動點擊同步，然後在執行發佈程式，想說用Apple Script 配合定期執行python語法，就可以Obsidian完成筆記後，直接PUSH 筆記的GitHub，然後在Mac電腦那邊就可以一氣呵成。&lt;/p&gt;
&lt;h2 id="_1"&gt;流程步驟&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;設定在電腦開啟時，一起啟動Obsidian軟體 &lt;/li&gt;
&lt;li&gt;等待同步程式執行&lt;/li&gt;
&lt;li&gt;加入 Automator 排程，讓 Mac 自動幫執行程式&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行內容程式順序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;判斷 Blog_Pelican 的Git 異動清單若是有修改則開始執行&lt;/li&gt;
&lt;li&gt;執行 pelican content 執行Blog建置，產生靜態Html檔&lt;/li&gt;
&lt;li&gt;Blog_Pelican 的 Git 執行 Commit 與 &lt;span class="caps"&gt;PUSH&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;參考：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://medium.com/pm%E7%9A%84%E7%94%9F%E7%94%A2%E5%8A%9B%E5%B7%A5%E5%85%B7%E7%AE%B1/%E7%82%BA%E4%BB%80%E9%BA%BC-mac-%E4%BD%BF%E7%94%A8%E8%80%85%E6%87%89%E8%A9%B2%E5%AD%B8%E7%BF%92-apple-script-13a599504362"&gt;為什麼 Mac 使用者應該學習 Apple Script？以 Evernote 舉例，自動建立每日反省筆記，自動化處理繁瑣流程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.minwt.com/mac/22625.html"&gt;&lt;span class="caps"&gt;MAC&lt;/span&gt; 設定 Shell Script(.sh) 檔，指定 終端機 將它開啟並自動執行&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="Automator"></category><category term="Mac"></category></entry><entry><title>英文快速學習祕技</title><link href="https://blog.richardnote.com/2022/01/how-learn-fast/" rel="alternate"></link><published>2022-01-13T14:42:00+08:00</published><updated>2022-01-13T14:42:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-13:/2022/01/how-learn-fast/</id><summary type="html">&lt;p&gt;如何快速學習任何語言的方法&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;如何快速學習任何語言的方法&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在很久以前看到這個YOUTUBE的影片，教學如何在六個月學習任何語言，而且是所謂的母語等級的學習，看完整理一下心得與筆記。&lt;/p&gt;
&lt;p&gt;影片原始路徑：&lt;/p&gt;
&lt;p&gt;How to learn any language in six months | Chris Lonsdale | TEDxLingnanUniversity&lt;/p&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/d0yGdNEWdn0" title="YouTube video player" width="560"&gt;&lt;/iframe&gt;
&lt;p&gt;整理影片內容主要的 七個行動、五大法則&lt;/p&gt;
&lt;h2 id="_2"&gt;七個行動&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;行動一：Listen A &lt;span class="caps"&gt;LOT&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[action1_listenALot.jpg]] ![[action1_usePatternsYouAlreadyKnow.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行動二：Focus on getting the meaning &lt;span class="caps"&gt;FIRST&lt;/span&gt;(before the words)
                  Use Patterns You Already Know  Vietnamese = 30% Mandarin + 30% Cantonese&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[action2_focusOnGettingTheMeaningFIRST.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;行動三：Start Mixing ！ 
                   10 Verbs  * 10 Nouns  * 10 Adjectives = 1000 Possible Phrases
![[action3_startMixing_1.jpg]] ![[action3_startMixing_2.jpg]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;行動四：Focus on the Core
                    High Frequency Language.3000 Words Gives 98% “Converage”
![[action4_FocusOnTheCore.jpg]]
![[action4_FocusOnTheCore1.jpg]]
![[action4_FocusOnTheCore2.jpg]] ![[action4_FocusOnTheCore3.jpg]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;行動五：Get A Language Parent&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[action5_GetALanguageParent.jpg]] ![[action5_GetALanguageParent1.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行動六：Copy The Face&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[action6_CopyTheFace.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行動七： Direct Connect to Mental Images&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[action7_DirectConnectToMentalImages.jpg]] ![[action7_DirectConnectToMentalImages1.jpg]]&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="_3"&gt;五大法則&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;法則一：Focus on language content that is relevant to you(專注關聯) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[principle1之一.jpg]] ![[principle1之二.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;法則二：Use your New Language as a Tool(活學活用)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[principle2.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;法則三：When you first &lt;span class="caps"&gt;UNDERSTAND&lt;/span&gt; the &lt;span class="caps"&gt;MESSAGE&lt;/span&gt; you will unconsciously &lt;span class="caps"&gt;ACQUIRE&lt;/span&gt; the Language(潛意識接收學習)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[principle3.jpg]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;法則四：Physilogical Training(口語練習) ![[principle4.jpg]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;法則五：Psycho-physiological &lt;span class="caps"&gt;STATE&lt;/span&gt; Matters(愉快學習)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[principle5之一.jpg]] ![[principle5之二.jpg]]&lt;/p&gt;</content><category term="英語學習"></category><category term="TED"></category><category term="English"></category></entry><entry><title>HTTP 請求方法</title><link href="https://blog.richardnote.com/2022/01/http-method/" rel="alternate"></link><published>2022-01-13T11:19:00+08:00</published><updated>2022-01-13T11:19:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-13:/2022/01/http-method/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;/1.1協定中共定義了八種方法（也叫「動作」）來以不同方式操作指定的資源&lt;/p&gt;</summary><content type="html">
&lt;p&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;/1.1協定中共定義了八種方法（也叫「動作」）來以不同方式操作指定的資源，在此先列出常用的方法來記錄，詳細的方法清單在下面連結的維基百科查看。&lt;/p&gt;
&lt;h4 id="get"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;a class="headerlink" href="#get" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;向指定的資源發出「顯示」請求。使用GET方法應該只用在讀取資料&lt;/p&gt;
&lt;h4 id="post"&gt;&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;a class="headerlink" href="#post" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;向指定資源提交資料，請求伺服器進行處理（例如提交表單或者上傳檔案）。 資料被包含在請求本文中。這個請求可能會建立新的資源或修改現有資源，或二者皆有。每次提交，表單的資料被瀏覽器用編碼到HTTP請求的body里。&lt;/p&gt;
&lt;p&gt;瀏覽器發出的POST請求的body主要有兩種格式：&lt;/p&gt;
&lt;p&gt;&lt;em&gt;1.一種是application/x-www-form-urlencoded用來傳輸簡單的資料，大概就是”key1=value1&amp;amp;key2=value2”這樣的格式。&lt;/em&gt;
&lt;em&gt;2.一種是傳檔案，會採用multipart/form-data格式。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;採用後者是因為application/x-www-form-urlencoded的編碼方式對於檔案這種二進位的資料非常低效。&lt;/p&gt;
&lt;h4 id="options"&gt;&lt;span class="caps"&gt;OPTIONS&lt;/span&gt;&lt;a class="headerlink" href="#options" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;這個方法可使伺服器傳回該資源所支援的所有HTTP請求方法。用  &lt;code&gt;*&lt;/code&gt; 來代替資源名稱，向Web伺服器傳送OPTIONS請求，可以測試伺服器功能是否正常運作。&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE"&gt;超文本傳輸協定&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="HTTP-METHOD"></category><category term="HTTP"></category></entry><entry><title>HTTP StatusCode 清單</title><link href="https://blog.richardnote.com/2022/01/http-status-code/" rel="alternate"></link><published>2022-01-13T11:04:00+08:00</published><updated>2022-01-13T11:04:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-13:/2022/01/http-status-code/</id><summary type="html">&lt;p&gt;記錄Http的狀態碼以待備查&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;所有HTTP回應的第一行都是&lt;strong&gt;狀態行&lt;/strong&gt;，依次是當前HTTP版本號，3位數字組成的&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81" title="HTTP狀態碼"&gt;狀態代碼&lt;/a&gt;，以及描述狀態的短語，彼此由空格分隔。&lt;/p&gt;
&lt;p&gt;狀態代碼的第一個數字代表當前回應的類型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81#1xx%E6%B6%88%E6%81%AF" title="HTTP狀態碼"&gt;1xx訊息&lt;/a&gt;——請求已被伺服器接收，繼續處理&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81#2xx%E6%88%90%E5%8A%9F" title="HTTP狀態碼"&gt;2xx成功&lt;/a&gt;——請求已成功被伺服器接收、理解、並接受&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81#3xx%E9%87%8D%E5%AE%9A%E5%90%91" title="HTTP狀態碼"&gt;3xx重新導向&lt;/a&gt;——需要後續操作才能完成這一請求&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81#4xx%E8%AF%B7%E6%B1%82%E9%94%99%E8%AF%AF" title="HTTP狀態碼"&gt;4xx請求錯誤&lt;/a&gt;——請求含有詞法錯誤或者無法被執行&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81#5xx%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%94%99%E8%AF%AF" title="HTTP狀態碼"&gt;5xx伺服器錯誤&lt;/a&gt;——伺服器在處理某個正確請求時發生錯誤&lt;/li&gt;
&lt;/ul&gt;</content><category term="網路概論"></category><category term="HTTP-STATUS"></category><category term="HTTP"></category></entry><entry><title>深入理解CORS</title><link href="https://blog.richardnote.com/2022/01/http-cors/" rel="alternate"></link><published>2022-01-12T15:44:00+08:00</published><updated>2022-01-12T15:44:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-12:/2022/01/http-cors/</id><summary type="html">&lt;p&gt;在兩次的錯誤後，好好的來理解所謂的CORS問題處理&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;前言&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在兩篇文章的洗禮後，好好的來理解所謂的CORS問題處理&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[[Fetch語法對Instagram的CORS問題]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[[IIS站臺對Options請求直接返回404]]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;W3C正式的CORS規範，其中，不單只是規範瀏覽器處理跨域請求的方式，也規範了伺服端可控制的項目，像是允許的來源、請求方法、可否發送Cookie、可取得的回應標頭，甚至回應有效期限等。&lt;/p&gt;
&lt;h2 id="http-headercors"&gt;Http Header的CORS項目&lt;a class="headerlink" href="#http-headercors" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="caps"&gt;CORS&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;Access-Control-Allow-Origin：&lt;ul&gt;
&lt;li&gt;server端接收跨來源時，授權來源，在Response加上此header，如果server允許任何來源的跨來源請求就使用  &lt;code&gt;*&lt;/code&gt; 號&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Credentials：&lt;ul&gt;
&lt;li&gt;設定值為True  False， 就是跨來源請求可以在Response時，取得一些cookie之類的資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Headers：&lt;ul&gt;
&lt;li&gt;用於響應預檢請求，以指示在發出實際請求時可以使用哪些 &lt;span class="caps"&gt;HTTP&lt;/span&gt; 標頭。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Methods：&lt;ul&gt;
&lt;li&gt;指定在訪問資源以響應預檢請求時允許的一種或多種方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Expose-Headers：&lt;ul&gt;
&lt;li&gt;指示哪些標頭可以作為響應的一部分公開，讓 JavaScript 存取其他 header&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Max-Age：&lt;ul&gt;
&lt;li&gt;指示預檢請求的結果可以緩存多長時間&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Request-Headers：&lt;ul&gt;
&lt;li&gt;在&lt;em&gt;發出預檢請求時使用&lt;/em&gt;，以讓服務器知道在發出實際請求時將使用哪些 &lt;span class="caps"&gt;HTTP&lt;/span&gt; 標頭。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Access-Control-Request-Method：&lt;ul&gt;
&lt;li&gt;在&lt;em&gt;發出預檢請求時使用&lt;/em&gt;，以讓服務器知道在發出實際請求時將使用哪種HTTP 方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Origin：指示提取的來源&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="corssimplewith-preflight"&gt;CORS將跨域請求分為：簡單（Simple），以及帶預檢（with Preflight）&lt;a class="headerlink" href="#corssimplewith-preflight" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;h2 id="_2"&gt;簡單請求&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方法只能是HEAD、&lt;span class="caps"&gt;GET&lt;/span&gt;、&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;可用標頭&lt;code&gt;Accept&lt;/code&gt;、&lt;code&gt;Accept-Language&lt;/code&gt;、&lt;code&gt;Content-Language&lt;/code&gt;、&lt;code&gt;Last-Event-ID&lt;/code&gt;，以及&lt;code&gt;Content-Type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Content-Type也只允許三個值&lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;、&lt;code&gt;multipart/form-data&lt;/code&gt;、&lt;code&gt;text/plain&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[簡單請求的圖例.png]]&lt;/p&gt;
&lt;h2 id="_3"&gt;預檢請求&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;分兩個步驟，第一步 http &lt;span class="caps"&gt;OPTIONS&lt;/span&gt; 方法，會帶有兩個 request header：&lt;code&gt;Access-Control-Request-Method&lt;/code&gt; 和 &lt;code&gt;Access-Control-Request-Headers&lt;/code&gt;。第二步在OPTIONS成功後，才能發送Request&lt;/p&gt;
&lt;p&gt;![[預檢請求的圖例.png]]&lt;/p&gt;
&lt;h2 id="fetch-api"&gt;關於fetch &lt;span class="caps"&gt;API&lt;/span&gt; 的問題&lt;a class="headerlink" href="#fetch-api" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;引用文章：&lt;/p&gt;
&lt;p&gt;很多人會認為只要將 fetch 裡的屬性 mode，調整成 &lt;code&gt;mode: 'no-cors'&lt;/code&gt;，就可以避免 &lt;span class="caps"&gt;CORS&lt;/span&gt;，其實不是！&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mode: 'no-cors&lt;/code&gt; 在設定上的意義是，告訴瀏覽器，我本來就知道 server 對於這個 request 是沒有設定可以存取 &lt;span class="caps"&gt;CORS&lt;/span&gt; 的，我本來就拿不到 response，我設定&lt;code&gt;mode: 'no-cors&lt;/code&gt;，是為了，就算無法存取，也不要跑到 .catch() 那邊，讓它出現 Error。&lt;/p&gt;
&lt;p&gt;一樣拿不到 server 的 response，但會拿到一個 &lt;code&gt;status: 0&lt;/code&gt; 的 response。&lt;/p&gt;
&lt;p&gt;結論：在 &lt;span class="caps"&gt;CORS&lt;/span&gt; 的限制底下，只有 server 開放 &lt;span class="caps"&gt;CORS&lt;/span&gt; 存取，你才拿得到 response，如果沒有開放，就一定拿不到。&lt;/p&gt;
&lt;p&gt;參考：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Headers"&gt;&lt;span class="caps"&gt;MDN&lt;/span&gt; Docs &lt;span class="caps"&gt;HTTP&lt;/span&gt; 標頭&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ithome.com.tw/voice/129558"&gt;深入認識跨域請求&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://shubo.io/what-is-cors/"&gt;&lt;span class="caps"&gt;CORS&lt;/span&gt; 是什麼? 如何設定 &lt;span class="caps"&gt;CORS&lt;/span&gt;?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://sa123.cc/mbz87ag1594xka2ohlgj.html"&gt;跨域（&lt;span class="caps"&gt;CORS&lt;/span&gt;）產生原因分析與解決方案，這一次徹底搞懂它&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/750548/"&gt;fetch捕獲重定向302/301&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.techbridge.cc/2017/05/20/api-ajax-cors-and-jsonp/"&gt;輕鬆理解 Ajax 與跨來源請求&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ithelp.ithome.com.tw/articles/10251693?sc=hot"&gt;[Day 27] Cross-Origin Resource Sharing (&lt;span class="caps"&gt;CORS&lt;/span&gt;)&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="CORS"></category></entry><entry><title>IIS站臺對Options請求直接返回404</title><link href="https://blog.richardnote.com/2022/01/iis-cors-404/" rel="alternate"></link><published>2022-01-12T14:40:00+08:00</published><updated>2022-01-12T14:40:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-12:/2022/01/iis-cors-404/</id><summary type="html">&lt;p&gt;在SignalR遇上CORS時IIS站臺設定的問題&lt;/p&gt;</summary><content type="html">
&lt;h2 id="signalr"&gt;SignalR的問題&lt;a class="headerlink" href="#signalr" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;之前在做SignalR的時候，需要對不同的子網域做API的呼叫，JS是在 signalr.domain.com ，需要呼叫的是在 o.domain.com 開始使用連線時，會引發CORS問題，如下圖：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;錯誤 ![[CorsPreflightError.png]]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SignalR在做options時，會用 https://signalr.domain.com/negotiate?negotiateVersion=1 這樣的路徑做預檢，不過查了老半天都是回404，檢查原因有可能如下：&lt;/p&gt;
&lt;h2 id="webconfigoptions"&gt;WebConfig是否被移除options請求的處理&lt;a class="headerlink" href="#webconfigoptions" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;system.webServer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;handlers&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;remove&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"OPTIONSVerbHandler"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/handlers&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/system.webServer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="iis-urlscanallowverbsoptions"&gt;檢查IIS是否安裝了 UrlScan的東西，若安裝了請檢查AllowVerbs中是否包含了options&lt;a class="headerlink" href="#iis-urlscanallowverbsoptions" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;UrlScan的配置文件為UrlScan.ini (C:\Windows\System32\inetsrv\urlscan\UrlScan.ini) 將OPTIONS從[DenyVerbs]中移除並添加到[AllowVerbs]下&lt;/p&gt;
&lt;p&gt;![[ISAPI篩選器的UrlScan.png]]&lt;/p&gt;
&lt;p&gt;![[UrlScan的設定.png]]&lt;/p&gt;
&lt;h2 id="webconfigallow-methodoptions"&gt;在站臺的webconfig中的Allow-Method中是否加上options&lt;a class="headerlink" href="#webconfigallow-methodoptions" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;system.webServer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;httpProtocol&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;customHeaders&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Methods"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"OPTIONS,POST,GET"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Headers"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"x-requested-with,aspxauth"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Credentials"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/customHeaders&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/httpProtocol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/system.webServer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.cnblogs.com/cplemom/p/10845434.html"&gt;IIS下網站對options請求直接返回404&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ithelp.ithome.com.tw/articles/10251693?sc=hot"&gt;Cross-Origin Resource Sharing (&lt;span class="caps"&gt;CORS&lt;/span&gt;)&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="CORS"></category><category term="IIS"></category><category term="微軟筆記"></category></entry><entry><title>Fetch語法對Instagram的CORS問題</title><link href="https://blog.richardnote.com/2022/01/cors-in-js-fix/" rel="alternate"></link><published>2022-01-11T22:07:00+08:00</published><updated>2022-01-11T22:07:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-11:/2022/01/cors-in-js-fix/</id><summary type="html">&lt;p&gt;Pelican的樣板。有提供一個功能在頁面可以嵌入&amp;nbsp;Instagram的PO文，使用方式就只需要定義一個DIV在Markdown的檔案中就可以嵌入&lt;/p&gt;</summary><content type="html">
&lt;p&gt;Pelican的樣板：  &lt;a href="https://github.com/Pelican-Elegant"&gt;Pelican-Elegant&lt;/a&gt;。有提供一個功能在頁面可以嵌入 Instagram的PO文，使用方式就只需要定義一個DIV在Markdown的檔案中就可以嵌入，&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"elegant-instagram"&lt;/span&gt; &lt;span class="na"&gt;data-instagram-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"BwWo35fAcR3"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中，data-instagram-id就是Instagram上面PO文時的連結路徑，不過使用過後出現CORS問題，在Github上面Issues也有
&lt;a href="https://github.com/Pelican-Elegant/elegant/issues/664"&gt;[&lt;span class="caps"&gt;BUG&lt;/span&gt;] Instagram code doesn’t work, browser shows blocked url because of policy&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;Access&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="s1"&gt;'https://www.instagram.com/p/YYYYYYYY/?__a=1'&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="s1"&gt;'https://MYURL'&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="nx"&gt;been&lt;/span&gt; &lt;span class="nx"&gt;blocked&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="nx"&gt;CORS&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="s1"&gt;'Access-Control-Allow-Origin'&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;present&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;requested&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;opaque&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="nx"&gt;serves&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="s1"&gt;'s mode to '&lt;/span&gt;&lt;span class="nx"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;CORS&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Instagram&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;shown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;由建議處理方式是fetch 加上 mode:’no-cors’&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instagramId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instagramId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`https://www.instagram.com/p/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;instagramId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/?__a=1`&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"no-cors"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;雖然不會出現CORS的問題了，但是IG的API回應卻是302 &lt;/p&gt;
&lt;p&gt;![[使用CORS後API變302回應.png]]&lt;/p&gt;
&lt;p&gt;![[已經修改fetch模式是nocors.png]]&lt;/p&gt;
&lt;p&gt;由於Response回應302，所以後續就直接錯誤了，認為應該是用fetch API去呼叫，會跳轉到IG的Login畫面，API是無法呈現的所以後續無法轉JSON格式，看來是需要增加access token變成登入狀態&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;access-control-expose-headers: X-IG-Set-WWW-Claim&lt;/span&gt;
&lt;span class="err"&gt;alt-svc: h3=":443"; ma=3600,h3-29=":443"; ma=3600&lt;/span&gt;
&lt;span class="err"&gt;cache-control: private, no-cache, no-store, must-revalidate&lt;/span&gt;
&lt;span class="err"&gt;content-language: zh-tw&lt;/span&gt;
&lt;span class="err"&gt;content-length: 0&lt;/span&gt;
&lt;span class="err"&gt;content-security-policy: report-uri https://www.instagram.com/security/csp_report/; default-src 'self' https://www.instagram.com; img-src data: blob: https://*.fbcdn.net https://*.instagram.com https://*.cdninstagram.com https://*.facebook.com https://*.fbsbx.com https://*.giphy.com; font-src data: https://*.fbcdn.net https://*.instagram.com https://*.cdninstagram.com; media-src 'self' blob: https://www.instagram.com https://*.cdninstagram.com https://*.fbcdn.net; manifest-src 'self' https://www.instagram.com; script-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://*.cdninstagram.com wss://www.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' https://*.www.instagram.com https://www.instagram.com 'unsafe-inline'; connect-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://graph.instagram.com https://*.graph.instagram.com https://i.instagram.com/graphql_www https://graphql.instagram.com https://*.cdninstagram.com https://api.instagram.com https://i.instagram.com https://*.i.instagram.com wss://www.instagram.com wss://edge-chat.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net chrome-extension://boadgeojelhgndaghljhdicfkmllpafd blob:; worker-src 'self' blob: https://www.instagram.com; frame-src 'self' https://instagram.com https://www.instagram.com https://*.instagram.com https://staticxx.facebook.com https://www.facebook.com https://web.facebook.com https://connect.facebook.net https://m.facebook.com; object-src 'none'; upgrade-insecure-requests&lt;/span&gt;
&lt;span class="err"&gt;content-type: text/html; charset=utf-8&lt;/span&gt;
&lt;span class="err"&gt;date: Wed, 12 Jan 2022 06:27:35 GMT&lt;/span&gt;
&lt;span class="err"&gt;expires: Sat, 01 Jan 2000 00:00:00 GMT&lt;/span&gt;
&lt;span class="err"&gt;location: https://www.instagram.com/accounts/login/&lt;/span&gt;
&lt;span class="err"&gt;pragma: no-cache&lt;/span&gt;
&lt;span class="err"&gt;set-cookie: mid=Yd501wALAAE2tYIXNpy3T6lgubqt; Domain=.instagram.com; expires=Fri, 12-Jan-2024 06:27:35 GMT; Max-Age=63072000; Path=/; Secure&lt;/span&gt;
&lt;span class="err"&gt;set-cookie: ig_did=B725DF97-76E5-4F3A-915A-366CD821B3A9; Domain=.instagram.com; expires=Fri, 12-Jan-2024 06:27:35 GMT; HttpOnly; Max-Age=63072000; Path=/; Secure&lt;/span&gt;
&lt;span class="err"&gt;set-cookie: ig_nrcb=1; Domain=.instagram.com; expires=Thu, 12-Jan-2023 06:27:35 GMT; Max-Age=31536000; Path=/; Secure&lt;/span&gt;
&lt;span class="err"&gt;strict-transport-security: max-age=31536000&lt;/span&gt;
&lt;span class="err"&gt;vary: Accept-Language, Cookie&lt;/span&gt;
&lt;span class="err"&gt;x-aed: 48&lt;/span&gt;
&lt;span class="err"&gt;x-content-type-options: nosniff&lt;/span&gt;
&lt;span class="err"&gt;x-fb-trip-id: 1679558926&lt;/span&gt;
&lt;span class="err"&gt;x-frame-options: SAMEORIGIN&lt;/span&gt;
&lt;span class="err"&gt;x-ig-origin-region: prn&lt;/span&gt;
&lt;span class="err"&gt;x-ig-push-state: c2&lt;/span&gt;
&lt;span class="err"&gt;x-ig-request-end-time: 1939701098&lt;/span&gt;
&lt;span class="err"&gt;x-ig-request-start-time: 1939701061.9430351&lt;/span&gt;
&lt;span class="err"&gt;x-xss-protection: 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;目前似乎無法針對 302 問題解決。若是做登入IG後，再次GET資料，雖然會有200的正常狀態，但是其實返回的物件是一個 &lt;code&gt;status:0&lt;/code&gt; 的情況， 參考了這篇： &lt;a href="https://ithelp.ithome.com.tw/articles/10249967"&gt;Fetch 的使用注意事項&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;![[IG回應的資歷形態.png]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;*引用：&lt;/p&gt;
&lt;p&gt;很多人會認為只要將 fetch 裡的屬性 mode，調整成 &lt;code&gt;mode: 'no-cors'&lt;/code&gt;，就可以避免 &lt;span class="caps"&gt;CORS&lt;/span&gt;，其實不是！
&lt;code&gt;mode: 'no-cors&lt;/code&gt; 在設定上的意義是，告訴瀏覽器，我本來就知道 server 對於這個 request 是沒有設定可以存取 &lt;span class="caps"&gt;CORS&lt;/span&gt; 的，我本來就拿不到 response，我設定&lt;code&gt;mode: 'no-cors&lt;/code&gt;，是為了，就算無法存取，也不要跑到 .catch() 那邊，讓它出現 Error。
一樣拿不到 server 的 response，但會拿到一個 &lt;code&gt;status: 0&lt;/code&gt; 的 response。*&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="cors-server-cors-response"&gt;結論：在 &lt;span class="caps"&gt;CORS&lt;/span&gt; 的限制底下，只有 server 開放 &lt;span class="caps"&gt;CORS&lt;/span&gt; 存取，你才拿得到 response，如果沒有開放，就一定拿不到。&lt;a class="headerlink" href="#cors-server-cors-response" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;https://www.ithome.com.tw/voice/129558&lt;/p&gt;
&lt;p&gt;https://shubo.io/what-is-cors/&lt;/p&gt;
&lt;p&gt;https://sa123.cc/mbz87ag1594xka2ohlgj.html&lt;/p&gt;
&lt;p&gt;https://codertw.com/%E7%A8%8B%E5%&lt;span class="caps"&gt;BC&lt;/span&gt;%8F%E8%&lt;span class="caps"&gt;AA&lt;/span&gt;%9E%E8%A8%80/750548/&lt;/p&gt;</content><category term="網路概論"></category><category term="CORS"></category></entry><entry><title>Instagram的記錄</title><link href="https://blog.richardnote.com/2022/01/instagram/" rel="alternate"></link><published>2022-01-11T16:06:00+08:00</published><updated>2022-01-11T16:06:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-01-11:/2022/01/instagram/</id><summary type="html">&lt;p&gt;測試&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;月眉濕地生態園區
&lt;div class="elegant-instagram" data-instagram-id="CYnUNkKonB9"&gt;&lt;/div&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="Life"></category><category term="Instagram"></category></entry><entry><title>ASP.NET MVC的參數驗證方式</title><link href="https://blog.richardnote.com/2021/12/asp-net-mvc-actionfilter/" rel="alternate"></link><published>2021-12-30T10:36:00+08:00</published><updated>2021-12-30T10:36:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-30:/2021/12/asp-net-mvc-actionfilter/</id><summary type="html">&lt;p&gt;用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; &lt;span class="caps"&gt;MVC&lt;/span&gt; 的&amp;nbsp;ActionFilterAttribute來過濾API參數&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;前言&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;有時提供廠商的API，明明沒有定義的參數卻帶入，或是已經是舊版不用的參數還是會帶入，使用這個方式來過濾並且阻擋，使用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; &lt;span class="caps"&gt;MVC&lt;/span&gt; 的 ActionFilterAttribute 方式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParaFilterAttribute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ActionFilterAttribute&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 交易類型 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ParaType&lt;/span&gt; &lt;span class="n"&gt;paraType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 比對Model名稱(MVC ModelBinding) &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ParameterName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnActionExecuting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ActionExecutingContext&lt;/span&gt; &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//取得傳入Model ApiModel &lt;/span&gt;
        &lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActionParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ParameterName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ApiModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//抓出交易類別的Property &lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetProperties&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IsNotParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;errorList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetErrorProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errorList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ContentResult&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;//返回錯誤&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 取得比對不符的參數 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetErrorProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiffValueType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiffRefType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 參考類型比較 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DiffRefType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValueType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 值類型比較 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DiffValueType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValueType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDefault&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 抓出要比較交易類別 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="p"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsNotParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ParaType&lt;/span&gt; &lt;span class="n"&gt;paraVal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ParamterAttribute&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParaType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;paraVal&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ParaType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="_2"&gt;欄位屬性這樣用&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;[Paramter(ParaType = 列舉物件)]&lt;/span&gt; 
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SomeModelPara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="filter"&gt;Filter這樣用&lt;a class="headerlink" href="#filter" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;[ParaFilter(ParaType = 列舉物件, ParameterName = "物件名稱")]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="ASPNETMVC"></category><category term="CSharp"></category></entry><entry><title>驗證的範例</title><link href="https://blog.richardnote.com/2021/12/some-verify-function/" rel="alternate"></link><published>2021-12-30T10:24:00+08:00</published><updated>2021-12-30T10:24:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-30:/2021/12/some-verify-function/</id><summary type="html">&lt;p&gt;記錄一些驗證規格的函數&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;身份驗證&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CheckIDNO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;       &lt;span class="c1"&gt;//除了檢查碼外每個數字的存放空間 &lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;charMapping&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"F"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"G"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"H"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"J"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"K"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"L"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"N"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"P"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"T"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"U"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"V"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"W"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"I"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"O"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;//A=10 B=11 C=12 D=13 E=14 F=15 G=16 H=17 J=18 K=19 L=20 M=21 N=22 &lt;/span&gt;

    &lt;span class="c1"&gt;//P=23 Q=24 R=25 S=26 T=27 U=28 V=29 X=30 Y=31 W=32  Z=33 I=34 O=35 &lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;charMapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charMapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;//10進制的高位元放入存放空間 &lt;/span&gt;
            &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//10進制的低位元*9後放入存放空間 &lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;//將剩餘數字乘上權數後放入存放空間 &lt;/span&gt;
        &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//檢查是否符合檢查規則，10減存放空間所有數字和除以10的餘數的個位數字是否等於檢查碼 &lt;/span&gt;
    &lt;span class="c1"&gt;//(10 - ((seed[0] + .... + seed[9]) % 10)) % 10 == 身分證字號的最後一碼 &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="_2"&gt;統編驗證&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CheckCompanyN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;addition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;addition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;addition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="email"&gt;Email驗證&lt;a class="headerlink" href="#email" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;RegExString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"^((([A-Za-z]|\d|[!#\$%&amp;amp;'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([A-Za-z]|\d|[!#\$%&amp;amp;'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="_3"&gt;手機驗證&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;RegExString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"[0-9\#\+\-\(\)]"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="fction"></category><category term="CSharp"></category></entry><entry><title>ASP.NET CORE 在IIS錯誤問題</title><link href="https://blog.richardnote.com/2021/12/aspnetcore-iis-error/" rel="alternate"></link><published>2021-12-10T09:44:00+08:00</published><updated>2021-12-10T09:44:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-10:/2021/12/aspnetcore-iis-error/</id><summary type="html">&lt;p&gt;預覽標題&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;![[IIS錯誤問題.png]]&lt;/p&gt;
&lt;p&gt;在IIS上執行ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; core&amp;nbsp;需要安裝：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="caps"&gt;NET&lt;/span&gt; Core的程式&amp;nbsp;aspnetcore-runtime-3.1.11-win-x64&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="caps"&gt;NET&lt;/span&gt; Core 裝載套件組合&amp;nbsp;dotnet-hosting-3.1.11-win&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://docs.microsoft.com/zh-tw/aspnet/core/tutorials/publish-to-iis?view=aspnetcore-5.0&amp;amp;tabs=netcore-cli"&gt;這是微軟的官方說明教學&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="ASPNETCore"></category><category term="IIS"></category><category term="微軟筆記"></category></entry><entry><title>OrchardCore CMS系統</title><link href="https://blog.richardnote.com/2021/12/orchardcode-cms/" rel="alternate"></link><published>2021-12-01T11:12:00+08:00</published><updated>2021-12-01T11:12:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-01:/2021/12/orchardcode-cms/</id><summary type="html">&lt;p&gt;記錄使用OrchardCodeCMS的學習歷程&lt;/p&gt;</summary><content type="html">
&lt;h2 id="net-coresdk"&gt;安裝 .&lt;span class="caps"&gt;NET&lt;/span&gt; Core與SDK&lt;a class="headerlink" href="#net-coresdk" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;OrchardCore CMS安裝流程在MAC上，主要在非Windows系統的安裝流程。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;主要參考：&lt;a href="https://github.com/orchardcmsnet/MyOrchardCoreCMSonLinuxUsingVSCode"&gt;https://github.com/orchardcmsnet/MyOrchardCoreCMSonLinuxUsingVSCode&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;另外NET CORE的Runtime安裝參考微軟官方：&lt;a href="https://docs.microsoft.com/zh-tw/dotnet/core/install/linux-ubuntu#how-to-install-other-versions"&gt;https://docs.microsoft.com/zh-tw/dotnet/core/install/linux-ubuntu#how-to-install-other-versions&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用Chrome的瀏覽器，因為不是Https，會自動將後臺登入自動導302Found問題，導致後臺登入一直出現在登入頁面，改用FireFox就可以&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;另外 aspnetcore-runtime-3.1 皆改用3.1似乎才能正常運作&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是注意目前.net core 已經到5.0 ，這個CMS框架只支援3.0&lt;/p&gt;
&lt;p&gt;安裝另外執行以下語法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;mv&lt;/span&gt; &lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trusted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//packages.microsoft.com/config/ubuntu/20.04/prod.list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;mv&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;chown&lt;/span&gt; &lt;span class="nl"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trusted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;chown&lt;/span&gt; &lt;span class="nl"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;aspnetcore&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.1&lt;/span&gt;


&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;mv&lt;/span&gt; &lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trusted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//packages.microsoft.com/config/ubuntu/20.04/prod.list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;mv&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;chown&lt;/span&gt; &lt;span class="nl"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trusted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;chown&lt;/span&gt; &lt;span class="nl"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="orchard-core"&gt;Orchard Core的所有功能概述¶&lt;a class="headerlink" href="#orchard-core" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;這是Orchard Core所有內置功能的分類概覽。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;參考: &lt;a href="https://docs.orchardcore.net/en/dev/docs/reference/"&gt;https://docs.orchardcore.net/en/dev/docs/reference/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;admin&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;App Security&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Authentication and User Management&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Content&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Design&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensibility&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hosting and Operations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Localization&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search, Indexing, Querying&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面就先記錄一下最主要的功能Content Type&lt;/p&gt;
&lt;h3 id="content-type"&gt;Content Type(內容類別)&lt;a class="headerlink" href="#content-type" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Content Type：選擇內容類型列表&lt;/p&gt;
&lt;p&gt;簡單說明就是頁面的顯示自定義類型，像是產品頁面類型，首頁頁面類型，部落格頁面類型，等等的分別，&lt;/p&gt;
&lt;p&gt;例如：IndexPage 可以定義為首頁，ProductListPage可以定義為產品列表頁面，ProductPage可以定義為產品頁面&lt;/p&gt;
&lt;p&gt;Content Type 裡面會有兩個部分組成&lt;/p&gt;
&lt;p&gt;Content Parts ，Content Field&lt;/p&gt;
&lt;h3 id="content-parts"&gt;Content Parts(內容部分)&lt;a class="headerlink" href="#content-parts" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;![[contentParts的功能.png]]&lt;/p&gt;
&lt;p&gt;該Title模塊提供了標題部分，使您可以自定義內容項的DisplayText屬性。整個管理界面都使用DisplayText屬性來幫助您識別內容項。&lt;/p&gt;
&lt;p&gt;標題部分¶ 將此部分附加到您的內容項以自定義ContentItem的DisplayText屬性。&lt;/p&gt;
&lt;p&gt;TitlePart設置¶ 默認情況下，附加TitlePart將允許內容編輯器手動編輯ContentItem的DisplayText（標題）。&lt;/p&gt;
&lt;p&gt;您也可以通過使用Liquid表達式指定模式來生成標題。&lt;/p&gt;
&lt;p&gt;模式有權訪問當前的ContentItem，並在ContentItem更新時執行。例如，字段可用於生成圖案。以下示例在內容類型上使用名為的Text字段。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;ContentItem.Content.Product.Name.Text&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="content-fields"&gt;Content Fields(內容欄位)&lt;a class="headerlink" href="#content-fields" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;![[contentFields的功能.png]]&lt;/p&gt;</content><category term="網路概論"></category><category term="OrchardCodeCMS"></category><category term="微軟筆記"></category></entry><entry><title>內容管理系統CMS</title><link href="https://blog.richardnote.com/2021/12/python-cms/" rel="alternate"></link><published>2021-12-01T09:58:00+08:00</published><updated>2021-12-01T09:58:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-01:/2021/12/python-cms/</id><summary type="html">&lt;p&gt;使用CMS系統建構網站&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;需求&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;需要建置一個快速的內容形象網站，最好的就是找CMS系統，以目前學的C#，還有新手Python程度，找到有幾個CMS來選擇&lt;/p&gt;
&lt;h3 id="djangocms-wagtailcms-orchardcodecms"&gt;DjangoCMS WagtailCMS  OrchardCodeCMS&lt;a class="headerlink" href="#djangocms-wagtailcms-orchardcodecms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OrchardCodeCMS&lt;/li&gt;
&lt;li&gt;WagtailCMS&lt;/li&gt;
&lt;li&gt;DjangoCMS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最後選擇使用WagtailCMS來處理我的需求以及找到一個套件能快速建構內容網站。&lt;/p&gt;
&lt;h2 id="orchardcodecms"&gt;OrchardCodeCMS&lt;a class="headerlink" href="#orchardcodecms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;使用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 來建置CMS系統，.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 目前還沒學到，而且我比較偏向使用Python來學習順便練習，但是這個OrchardCoreCMS內容功能蠻強大的，而且也蠻靈活的，由於NET Core 已經可以跨平臺，所以在我的Mac也可以建置。使用Visual Studio 2019 開啟，直接建置完成，啟動後，就直接一個設定頁面可以選擇，資料庫提供SQLite，&lt;span class="caps"&gt;SQL&lt;/span&gt; Server，還有一些基本的樣板，提供基本的Agency，Blog，ComingSoom 等的樣板。&lt;/p&gt;
&lt;p&gt;![[OrchardCodeCMS開始設定頁面.jpg]]&lt;/p&gt;
&lt;p&gt;![[可以設定版型.jpg]]&lt;/p&gt;
&lt;p&gt;![[Pastedimage20211201104159.png]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;節錄一下官方文件的重點：&lt;/p&gt;
&lt;p&gt;不同的網站建設策略¶
Orchard Core CMS支持所有主要的網站建設策略：&lt;/p&gt;
&lt;p&gt;完整的CMS。在這種模式下，網站使用主題和模板來呈現您的內容，目的是實現很少甚至沒有自定義開發。&lt;/p&gt;
&lt;p&gt;解耦CMS。除了內容管理後端之外，該網站一開始是空白。您可以使用Razor Pages或MVC操作創建所需的所有模板，並通過內容服務訪問內容。
參考：&lt;a href="https://www.youtube.com/watch?v=yWpz8p-oaKg"&gt;https://www.youtube.com/watch?v=yWpz8p-oaKg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;無頭CMS。該站點僅管理內容，並且您創建了一個單獨的應用程序，該應用程序將使用GraphQL或REST API來獲取託管內容。
參考：&lt;a href="https://www.youtube.com/watch?v=4o9zG17cfa0"&gt;https://www.youtube.com/watch?v=4o9zG17cfa0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;解耦CMS比較適合拿來做客製化的樣板網站，對於OrchardCodeCMS功能的理解，另外鏈結一篇文章: [[OrchardCore CMS系統]] ，內容之多對於我只是想要簡單的內容展示形象網站似乎有點大，先放著以後再來學好了。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="djangocmswagtailcms"&gt;DjangoCMS與WagtailCMS&lt;a class="headerlink" href="#djangocmswagtailcms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DjangoCMS之前有稍微研究一下官方提供的測試後臺，玩了一下，對於我這個Python新手而言，還有操作上，覺得有點不直覺，後來就跑去看WagtailCMS，對於想要快速建構一個Blog或是小型形象網站，WagtailCMS似乎比較能夠達成我的需求，而且還不太會寫Python的我&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLMQHMcNi6ocsS8Bfnuy_IDgJ4bHRRrvub"&gt;https://www.youtube.com/playlist?list=PLMQHMcNi6ocsS8Bfnuy_IDgJ4bHRRrvub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Youtube上的Wagtail學習系列影片，相關的教學還蠻多的，個人覺得WagtailCMS，也還是需要一點程式底子去處理細微的修改，但是後來發現一個好套件。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/coderedcorp/coderedcms"&gt;CodeRed &lt;span class="caps"&gt;CMS&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這個CodeRed像是Wagtail的加強版，把很多想要的功能都做好了，&lt;/p&gt;
&lt;p&gt;![[RedcodeCMS的功能項目.jpg]]&lt;/p&gt;
&lt;p&gt;一開始還不太懂架構的堆疊，後來摸熟之後，就像是在玩疊積木一樣，能夠快速的建立一個小站臺，非要說缺點就是要精確的調整樣式的話，會比較麻煩，若是有設計的人員可能比較好，基本上CodeRed套件樣式是使用 &lt;a href="https://bootswatch.com/lux/"&gt;https://bootswatch.com/lux/&lt;/a&gt; 基本的版型。&lt;/p&gt;
&lt;p&gt;以上就是碰過的內容管理系統，各個架構都感覺不錯，各有長處，但是以本業是微軟方面的我，OrchardCodeCMS可以好好學學看，可以學到蠻多東西，而且 .&lt;span class="caps"&gt;NET&lt;/span&gt; Core 是微軟較新的技術，順便練習。&lt;/p&gt;</content><category term="後端程式"></category><category term="WagtailCMS"></category><category term="CodeRedCMS"></category><category term="Python"></category></entry><entry><title>Python爬蟲程式錯誤</title><link href="https://blog.richardnote.com/2021/11/python-crawler-error/" rel="alternate"></link><published>2021-11-25T23:04:00+08:00</published><updated>2021-11-25T23:04:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-25:/2021/11/python-crawler-error/</id><summary type="html">&lt;p&gt;ConnectionResetError(54,&amp;#8217;Connection reset by&amp;nbsp;peer&amp;#8217;))&lt;/p&gt;</summary><content type="html">
&lt;h2 id="traceback"&gt;錯誤發生的Traceback&lt;a class="headerlink" href="#traceback" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;438&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_error_catcher&lt;/span&gt;

 &lt;span class="k"&gt;yield&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;767&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read_chunked&lt;/span&gt;

 &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_handle_chunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;711&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_handle_chunk&lt;/span&gt;

 &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_safe_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/http/client.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;625&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_safe_read&lt;/span&gt;

 &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAXAMOUNT&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/socket.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;704&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;readinto&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recv_into&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/ssl.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1241&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;recv_into&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nbytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/ssl.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1099&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sslobj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Errno&lt;/span&gt; &lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt;



&lt;span class="n"&gt;During&lt;/span&gt; &lt;span class="n"&gt;handling&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;above&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="n"&gt;occurred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;753&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;

 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;

 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_chunked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;793&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read_chunked&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_original_response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/contextlib.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;137&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="fm"&gt;__exit__&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;traceback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;455&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_error_catcher&lt;/span&gt;

 &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ProtocolError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: &lt;/span&gt;&lt;span class="si"&gt;%r&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;urllib3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProtocolError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: ConnectionResetError(54, 'Connection reset by peer')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Connection reset by peer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;



&lt;span class="n"&gt;During&lt;/span&gt; &lt;span class="n"&gt;handling&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;above&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="n"&gt;occurred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/FileSource/batch_stock.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

 &lt;span class="n"&gt;auto_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'otc_cap_reduction'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crawl_otc_cap_reduction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/FileSource/batch_stock.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;auto_update&lt;/span&gt;

 &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crawl_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/finlab/crawlers/api.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;454&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;crawl_otc_cap_reduction&lt;/span&gt;

 &lt;span class="n"&gt;res4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urs_crawl_otc_cap_reduction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/finlab/crawlers/helper.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;363&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;requests_get&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;555&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;542&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;

 &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;send_kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;697&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;

 &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;831&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONTENT_CHUNK_SIZE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;756&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;

 &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ChunkedEncodingError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChunkedEncodingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: ConnectionResetError(54, 'Connection reset by peer')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Connection reset by peer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="_1"&gt;問題原因&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;參考：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/59851207/connectionreseterror-with-requests-module-raises-exception-inside-of-exception"&gt;帶有請求模塊的 ConnectionResetError 在異常內部引發異常，使程序崩潰&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由參考的資訊來看，我的發生也是依序發生&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ConnectionResetError: [Errno 54] Connection reset by peer&lt;/li&gt;
&lt;li&gt;urllib3.exceptions.ProtocolError: (“Connection broken: ConnectionResetError(54, ‘Connection reset by peer’)”, ConnectionResetError(54, ‘Connection reset by peer’))&lt;/li&gt;
&lt;li&gt;requests.exceptions.ChunkedEncodingError: (“Connection broken: ConnectionResetError(54, ‘Connection reset by peer’)”, ConnectionResetError(54, ‘Connection reset by peer’))&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由第三點的說明來看，是連線已經中斷了，而導致程式Crash，原本的程式在request的寫法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ReadTimeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;看來只有ConnectionError或Timeout才會被忽略，再新增&lt;code&gt;ConnectionResetError&lt;/code&gt; 再來觀察看看連線中斷的問題，避免程式因為斷線而Crash，在except內再重新request&lt;/p&gt;</content><category term="後端程式"></category><category term="ConnectionResetError"></category><category term="Python"></category></entry><entry><title>ASCII認識</title><link href="https://blog.richardnote.com/2021/11/ascii/" rel="alternate"></link><published>2021-11-22T18:27:00+08:00</published><updated>2021-11-22T18:27:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-22:/2021/11/ascii/</id><summary type="html">&lt;p&gt;程式在使用XML的序列化時發生十六進位值(0x08)是無效的字&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;錯誤&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;發生錯誤訊息如下，程式在使用XML的序列化時發生這樣的錯誤&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ErrorMsg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;產生&lt;/span&gt; &lt;span class="n"&gt;XML&lt;/span&gt; &lt;span class="err"&gt;文件時發生錯誤。&lt;/span&gt; &lt;span class="p"&gt;---&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;十六進位值&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="n"&gt;x08&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;是無效的字元。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查詢問題後發現文字內有特殊的符號 &lt;span class="caps"&gt;EX&lt;/span&gt; ： &lt;/p&gt;
&lt;p&gt;![[Pasted image 20211123110703.png]]&lt;/p&gt;
&lt;p&gt;測試程式有特殊符號，會Exception在&lt;code&gt;xmlSerializer.Serialize&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;xmlData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;oData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inputText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"測試_測試測試測試測試測試"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// 序列化為XML。&lt;/span&gt;
        &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialization&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XmlSerializer&lt;/span&gt; &lt;span class="n"&gt;xmlSerializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialization&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XmlSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;XmlWriterSettings&lt;/span&gt; &lt;span class="n"&gt;xmlSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;XmlWriterSettings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Big5"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Indent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OmitXmlDeclaration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StringWriter&lt;/span&gt; &lt;span class="n"&gt;szWriter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StringWriter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XmlWriter&lt;/span&gt; &lt;span class="n"&gt;xmlWriter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XmlWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;szWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;xmlSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xmlWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;xmlData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;szWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xmlData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中的特殊符號在ASCII表轉換成 16進制的 08，是算ASCII的控制字元，無法轉換。&lt;/p&gt;
&lt;h2 id="ascii"&gt;ASCII碼表&lt;a class="headerlink" href="#ascii" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;整理一下代碼的意義：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第0～32號及第127號(共34個)是控制字元或通訊專用字元&lt;/li&gt;
&lt;li&gt;第33～126號(共94個)是字元&lt;/li&gt;
&lt;li&gt;第48～57號為0～9十個阿拉伯數字&lt;/li&gt;
&lt;li&gt;第65～90號為26個大寫英文字母&lt;/li&gt;
&lt;li&gt;第97～122號為26個小寫英文字母，其餘為一些標點符號、運算符號&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;![[&lt;span class="caps"&gt;ASCII&lt;/span&gt;.gif]]&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm"&gt;ASCII碼介紹&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://idv.sinica.edu.tw/bear/charcodes/Section02.htm"&gt;認識中文字元碼&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="ascii"></category><category term="微軟筆記"></category></entry><entry><title>使用Bokeh產生技術圖表</title><link href="https://blog.richardnote.com/2021/11/shi-yong-bokehchan-sheng-ji-shu-tu-biao/" rel="alternate"></link><published>2021-11-03T11:05:00+08:00</published><updated>2021-11-03T11:05:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-03:/2021/11/shi-yong-bokehchan-sheng-ji-shu-tu-biao/</id><summary type="html">&lt;p&gt;在Django上套用Bokeh產生技術圖表&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;參考資料：
&lt;a href="https://www.finlab.tw/bokeh-stock-chart-with-technical-analysis/"&gt;Bokeh 探索頻道(2)~客製化技術圖表升級&lt;/a&gt;
&lt;a href="https://www.jianshu.com/p/8b4f17950777"&gt;在 Django 上使用数据可视化利器&amp;nbsp;Bokeh&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;![[bokeh指標views圖.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;參考老師的Blog文章，內附的程式碼就可以無痛升級美麗圖表，但是我架設在Django上，需要調整一下來顯示在Django頁面。&lt;/p&gt;
&lt;p&gt;在Django的View.py&amp;nbsp;上收先引用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bokeh.embed&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bokeh.resources&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CDN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;在程式加入Blog內的function來產生資料跟已經畫好的圖表，使用components，產生javascript與 html區塊，最後在render頁面帶入參數
![[bokeh指標views圖1.png]]&amp;nbsp;![[bokeh指標views圖2.png]]&lt;/p&gt;
&lt;p&gt;在Django的templates頁面上，下圖是圖表的Html的Div區塊&amp;nbsp;![[bokeh指標templates圖1.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;下圖是在&lt;code&gt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; 區塊中，先引用bokeh的js，我直接下載到我的本機，避免版本到時候又變了壞掉，最後使用bokeh產生的的javascript語法。&amp;nbsp;![[bokeh指標templates圖2.png]]&lt;/p&gt;
&lt;p&gt;就可以產生美美的圖了&amp;nbsp;![[bokeh指標總圖.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="Python"></category><category term="Bokeh"></category></entry><entry><title>MacM1執行Tensorflow錯誤問題</title><link href="https://blog.richardnote.com/2021/10/mac-tensorflow/" rel="alternate"></link><published>2021-10-28T07:50:00+08:00</published><updated>2021-10-28T07:50:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-28:/2021/10/mac-tensorflow/</id><summary type="html">&lt;p&gt;MacM1執行Tensorflow2.6出現錯誤&lt;/p&gt;</summary><content type="html">&lt;p&gt;每當執行如下的語法時：
&lt;code&gt;model.fit(x_train, y_train, epochs=5)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;就會出現以下錯誤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;06.945996&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mlir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mlir_graph_optimization_pass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;185&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;None&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;MLIR&lt;/span&gt; &lt;span class="n"&gt;Optimization&lt;/span&gt; &lt;span class="n"&gt;Passes&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="nf"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registered&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;06.948454&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;profile_utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cpu_utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;Hz&lt;/span&gt;

&lt;span class="n"&gt;Epoch&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.052295&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;grappler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;optimizers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;custom_graph_optimizer_registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;112&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt; &lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt; &lt;span class="n"&gt;GPU&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.079&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8109&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;118092&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-[&lt;/span&gt;&lt;span class="n"&gt;MPSGraph&lt;/span&gt; &lt;span class="n"&gt;adamUpdateWithLearningRateTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;epsilonTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valuesTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;momentumTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;velocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;maximumVelocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gradientTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unrecognized&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="mh"&gt;0x29ee0f660&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.091&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8109&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;118092&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;***&lt;/span&gt; &lt;span class="n"&gt;Terminating&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;uncaught&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;NSInvalidArgumentException&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;-[&lt;/span&gt;&lt;span class="n"&gt;MPSGraph&lt;/span&gt; &lt;span class="n"&gt;adamUpdateWithLearningRateTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;epsilonTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valuesTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;momentumTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;velocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;maximumVelocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gradientTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unrecognized&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="mh"&gt;0x29ee0f660&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;hr /&gt;
&lt;p&gt;一開始以爲是只能執行在Python 3.8的環境，但是參考教學 https://www.youtube.com/watch?v=_CO-&lt;span class="caps"&gt;ND1FTOU&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;影片中也是能夠在Python3.9使用Tensorflow2.5，使用以下語法查看版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sklearn&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;sk&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;tensorflow&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;tf&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tensor Flow Version: {tf.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Keras Version: {tensorflow.keras.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Python {sys.version}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pandas {pd.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Scikit-Learn {sk.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;gpu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_physical_devices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GPU&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GPU is&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;available&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;NOT AVAILABLE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Tensor Flow Version: 2.6.0
Keras Version:&amp;nbsp;2.6.0&lt;/p&gt;
&lt;p&gt;Python 3.9.6 | packaged by conda-forge | (default, Jul 11 2021, 03:35:11) 
[Clang 11.1.0 ]
Pandas 1.3.0
Scikit-Learn 0.24.2
&lt;span class="caps"&gt;GPU&lt;/span&gt; is&amp;nbsp;available&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;用另外一個環境一樣Python3.9，TensorFlow2.5就可以正確執行，看來需要降版本，只好先移除了&lt;/p&gt;
&lt;p&gt;安裝參考：
&lt;a href="https://developer.apple.com/metal/tensorflow-plugin/"&gt;tensorflow-metal PluggableDevice&amp;nbsp;入門&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://makeoptim.com/deep-learning/tensorflow-metal"&gt;&lt;span class="caps"&gt;AI&lt;/span&gt; - Apple Silicon Mac M1 原生支持 TensorFlow 2.6 &lt;span class="caps"&gt;GPU&lt;/span&gt; 加速（tensorflow-metal&amp;nbsp;PluggableDevice）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;參考第二個連接的處理，重新安裝 Xcode&amp;nbsp;，並且重新執行安裝語法就OK了&lt;/p&gt;
&lt;p&gt;先解除安裝
&lt;code&gt;python -m pip uninstall tensorflow-macos&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip uninstall tensorflow-metal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;執行重新安裝
&lt;code&gt;conda install -c apple tensorflow-deps --force-reinstall&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip install tensorflow-macos&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip install tensorflow-metal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;測試語法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;layers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxPooling2D&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxPooling2D&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flatten&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;softmax&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras.datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mnist&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mnist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;train_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;train_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
&lt;span class="n"&gt;test_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;test_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
&lt;span class="n"&gt;train_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rmsprop&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;categorical_crossentropy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accuracy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;epochs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_loss&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_acc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;上面處理已經完成但是會引發一個問題：&lt;/p&gt;
&lt;p&gt;numpy&amp;nbsp;會被安裝成0.19的版本，而且會造成錯誤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;ValueError:&lt;/span&gt;
&lt;span class="n"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ndarray&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;indicate&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="n"&gt;incompatibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Expected&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;需要再更新Numpy&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="TensorFlow"></category><category term="Mac"></category></entry><entry><title>本益比</title><link href="https://blog.richardnote.com/2021/10/ben-yi-bi/" rel="alternate"></link><published>2021-10-13T13:27:00+08:00</published><updated>2021-10-13T13:27:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-13:/2021/10/ben-yi-bi/</id><summary type="html">&lt;p&gt;用來衡量股價的『投資回本的速度』&lt;/p&gt;</summary><content type="html">&lt;p&gt;$$ 本益比 = 股價 / 每股盈餘(&lt;span class="caps"&gt;EPS&lt;/span&gt;)&amp;nbsp;$$&lt;/p&gt;
&lt;p&gt;&lt;em&gt;以投資的角度來看，股價則是投資1股所需要的成本(購買成本)，而每股獲利意思是投資1股所得到的獲利，因此本益比就是投資該股票1股的成本與獲利的比值，即為報酬率的倒數。在合理本益比接近的條件下，較低的本益比通常代表著投資的潛在報酬較大。&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;心得：本益比的高低是相對的，主要要察覺這家公司的獲利能力與EPS再來對比本益比是否過高&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://statementdog.com/analysis/2392/pe"&gt;財報狗&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stockstore-tw.medium.com/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E6%9C%AC%E7%9B%8A%E6%AF%94-13dfdf5922b4"&gt;深入理解本益比&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="投資學習"></category><category term="本益比"></category><category term="價值評估分析"></category></entry><entry><title>安裝Let’s Encrypt電子證書</title><link href="https://blog.richardnote.com/2021/10/mac-lets-encrypt/" rel="alternate"></link><published>2021-10-08T18:45:00+08:00</published><updated>2021-10-08T18:45:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-08:/2021/10/mac-lets-encrypt/</id><summary type="html">&lt;p&gt;在Mac本機安裝SSL與驗證流程記錄&lt;/p&gt;</summary><content type="html">&lt;p&gt;在本機驗證安裝Let&amp;#8217;s&amp;nbsp;Encrypt&lt;/p&gt;
&lt;p&gt;&lt;code&gt;brew install certbot&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;brew ls certbot&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然後在Mac執行  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;certbot --config-dir ~/letsencrypt/etc --work-dir ~/letsencrypt/lib --logs-dir ~/letsencrypt/log certonly --manual&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接下來會有三個步驟要輸入：&lt;/p&gt;
&lt;p&gt;1.Email&lt;/p&gt;
&lt;p&gt;2.domain&lt;/p&gt;
&lt;p&gt;3.會要你在規定的路徑上產生讀取文檔：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Saving&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;letsencrypt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;letsencrypt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;

&lt;span class="n"&gt;Please&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;

&lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="n"&gt;separated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enter&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;c&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;

&lt;span class="n"&gt;Requesting&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;containing&lt;/span&gt; &lt;span class="n"&gt;just&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;YYUCwTYHewbZ0vVcobFBA8kmL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;AQAj5aH7tD3HI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mFCPG4KMVD6yTJlxRiPv1IXrYQENjpRSb9DJyynjW5I&lt;/span&gt;



&lt;span class="n"&gt;And&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;web&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;known&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;acme&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;challenge&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;YYUCwTYHewbZ0vVcobFBA8kmL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;AQAj5aH7tD3HI&lt;/span&gt;



&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="n"&gt;Press&lt;/span&gt; &lt;span class="n"&gt;Enter&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;從上面的指示來看&amp;nbsp;要在指定的網址：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;http://linebot.richardrobot.xyz/.well-known/acme-challenge/YYUCwTYHewbZ0vVcobFBA8kmL-xs-8AQAj5aH7tD3HI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;產生可讀取字串：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;YYUCwTYHewbZ0vVcobFBA8kmL-xs-8AQAj5aH7tD3HI.mFCPG4KMVD6yTJlxRiPv1IXrYQENjpRSb9DJyynjW5I&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="django"&gt;在Django的做法如下：&lt;a class="headerlink" href="#django" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在 url.py&amp;nbsp;設定網址：&lt;/p&gt;
&lt;p&gt;![[url設定的圖片.png]]&lt;/p&gt;
&lt;p&gt;檔案放置的地方：&amp;nbsp;![[檔案放置的地方.png]]&lt;/p&gt;
&lt;p&gt;Views.py 程式讀取的方式：&amp;nbsp;![[views程式讀取的方式.png]]&lt;/p&gt;
&lt;p&gt;驗證成功存放的路徑：&amp;nbsp;![[驗證成功的畫面.png]]&lt;/p&gt;
&lt;p&gt;nginx&amp;nbsp;新增的配置&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;第一個&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//linebot.richardrobot.xyz$request_uri;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;第二個&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;



&lt;span class="n"&gt;ssl&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;

&lt;span class="n"&gt;ssl_certificate&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;LineBot&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;

&lt;span class="n"&gt;ssl_certificate&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;LineBot&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;

&lt;span class="n"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;LineBot&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;privkey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;


    &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="cp"&gt;#第三個&lt;/span&gt;
        &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="err"&gt;這個很重要，記得加入&lt;/span&gt;


    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;沒有加最後的分號 ; 
(LineBot) jarvis.zheng@zhengruichangdeMac-mini LineBot % sudo nginx -s reload
Password:
nginx: [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in /opt/homebrew/etc/nginx/sites-enabled/LineBot:5
nginx: [emerg] no "ssl_certificate_key" is defined for certificate "/Users/jarvis.zheng/LineBot/ssl/chain.pem" and the "ssl" directive in /opt/homebrew/etc/nginx/sites-enabled/LineBot:5&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://yinlei.org/x-plane10/big5.php?p=2017/01/lets-encrypt.html"&gt;安裝Let&amp;#8217;s&amp;nbsp;Encrypt電子證書&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jerry.thesolarsystems.net/?p=885"&gt;如何在NGINX+DJANGO平台設置SSL連線&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="網路概論"></category><category term="SSL"></category><category term="Mac"></category></entry><entry><title>LineLogin串接</title><link href="https://blog.richardnote.com/2021/10/lineloginchuan-jie/" rel="alternate"></link><published>2021-10-08T08:38:00+08:00</published><updated>2021-10-08T08:38:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-08:/2021/10/lineloginchuan-jie/</id><summary type="html">&lt;p&gt;Django串街LineLogin &lt;span class="caps"&gt;API&lt;/span&gt;&amp;nbsp;流程簡單教學&lt;/p&gt;</summary><content type="html">&lt;p&gt;參考資料：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://jerrynest.io/django-allauth/"&gt;使用 Django Allauth 套件&lt;/a&gt;
&lt;a href="https://wreadit.com/@wwwlearncodewithmikecom/post/50134"&gt;[Django教學13]Django&amp;nbsp;Allauth套件整合Google登入驗證實作教學&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先安裝django-allauth&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pip install django-allauth&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在Django站臺的Settings設定相關的參數設定&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;INSTALLED_APPS&lt;/code&gt; 裏面新增 allauth allauth.account&amp;nbsp;&amp;#8230;以下的資料&lt;/li&gt;
&lt;li&gt;新增設定&lt;code&gt;AUTHENTICATION_BACKENDS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;新增設定&lt;code&gt;SITE_ID&lt;/code&gt; ,數值要比對Django資料表內的  django_site&amp;nbsp;的ID值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SOCIALACCOUNT_PROVIDERS&lt;/code&gt;這是要設定讀取使用者的資料&lt;/li&gt;
&lt;li&gt;在站臺的url.py設定路徑&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;![[settings設定參數1.png]]&amp;nbsp;![[settings設定參數二.png]]&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;admin/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accounts/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;allauth.urls&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;hr /&gt;
&lt;p&gt;以上設定完成要執行Django語法來產生資料表：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py makemigrations&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py migrate&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;以上就是Django的設定部分，另外LineLogin的設定需要注意的細節，因爲django-allauth已經將送LineLogin授權路徑參數自動拼裝好了，裏面有些規範需要注意&lt;/p&gt;
&lt;p&gt;在送授權的部分，django-allauth定義的callbackURL已經規範，如下圖
![[djangoallauth.png]]
&lt;a href="https://django-allauth.readthedocs.io/en/latest/providers.html#line"&gt;https://django-allauth.readthedocs.io/en/latest/providers.html#line&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;上面的 Callback &lt;span class="caps"&gt;URL&lt;/span&gt; 必須與LINE Login 內的設定相同&amp;nbsp;![[lineloginapi的設定.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;另外剩下的就是要設定KEY與ClientID:&lt;/p&gt;
&lt;p&gt;去內部後臺設定LINE SecrtKEY&amp;nbsp;![[linelogin內部後臺設定.png]]&lt;/p&gt;
&lt;p&gt;回到頁面去，雖然沒有寫什麼頁面，可是 django-allauth已經內建了許多頁面可以直接查看
![[linelogin預設路徑頁面.png]]&amp;nbsp;![[linelogin預設登入畫面.png]]&lt;/p&gt;
&lt;p&gt;以上就是完成初步的串街，內容套版需要再詳細實做與修改，另外在串街流程中發生的錯誤在導向到LineLogin畫面時出現 400 錯誤：&amp;nbsp;![[linelogin400錯誤情況.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;這個問題的發生原因先查看了LineLogin的文件說明&lt;/p&gt;
&lt;h2 id="_1"&gt;要求授權&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;為進行使用者認證，並為 app 要求權限，請透過所需的 query parameter，如下面例子所示將使用者重新導向授權 &lt;span class="caps"&gt;URL&lt;/span&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//access.line.me/oauth2/v2.1/authorize?&lt;/span&gt;
&lt;span class="n"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1234567890&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="n"&gt;abcde&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;openid&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;09876&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;![[linelogin串街參數.png]]&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developers.line.biz/zh-hant/docs/line-login/integrate-line-login/#making-an-authorization-request"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&amp;nbsp;的查詢屬性&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我的參數：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;access&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;oauth2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;authorize&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;

&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;U2c2bde960c5d7723082f2b9a491f51e1&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BBwcp2EEdqnJ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;錯誤問題1：client_id不對
client_id ：&lt;span class="caps"&gt;LINE&lt;/span&gt; Login Channel 的 Channel &lt;span class="caps"&gt;ID&lt;/span&gt;
錯誤問題2：scope沒有值&amp;nbsp;scope：向用戶請求授予權限，也就是要求取得使用者的資料&lt;/p&gt;
&lt;p&gt;修正：
1.在admin後臺修改設定
2.在settings.py新增如下參數：&amp;nbsp;![[linelogin新增參數.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="LineLoginAPI"></category><category term="LineBot"></category><category term="Django"></category></entry><entry><title>Supervisor</title><link href="https://blog.richardnote.com/2021/10/mac-supervisor/" rel="alternate"></link><published>2021-10-05T19:22:00+08:00</published><updated>2021-10-05T19:22:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-05:/2021/10/mac-supervisor/</id><summary type="html">&lt;p&gt;在Mac上使用supervisor來啓動服務&lt;/p&gt;</summary><content type="html">&lt;p&gt;在 Linux上可以使用systemctl&amp;nbsp;這個服務來開機就能自動啓動寫好的網站服務，等等其他的，但是在Mac上卻無法，使用supervisor還有Web畫面可以查看&lt;/p&gt;
&lt;p&gt;![[Supervisor服務畫面.png]]&lt;/p&gt;
&lt;h2 id="brew"&gt;透過brew來安裝：&lt;a class="headerlink" href="#brew" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;brew install supervisor&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="_1"&gt;設定檔路徑：&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;由於是Mac M1 的系統，homebrew已經將設定的路徑放在 &lt;code&gt;/opt/homebrew/etc&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如下圖，開啓 supervisor.conf&amp;nbsp;檔案&lt;/p&gt;
&lt;p&gt;![[supervisor的ini設定畫面.png]]&lt;/p&gt;
&lt;p&gt;可以註解前面的 &lt;code&gt;;&lt;/code&gt; 符號來啓用設定&amp;nbsp;:&lt;/p&gt;
&lt;p&gt;可以開啓 Web的畫面 啓用&amp;nbsp;登入帳號密碼&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;inet_http_server&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;          &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;disabled&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9001&lt;/span&gt;         &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;specifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt; &lt;span class="n"&gt;iface&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;               &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;                &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;在最後加入客製化的設定檔：
加入下面的設定，可以在/Process/  資料夾底下設定需要的Service檔，並且用 .ini&amp;nbsp;爲副檔名&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ini&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;已django網站爲例：&lt;/p&gt;
&lt;p&gt;command 程序啓動命令：使用gunicorn來當WebServer，使用參數檔&amp;nbsp;gunicorn.conf.py &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;django_server&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;miniforge3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;envs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;finlab&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;StockSecretary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wsgi&lt;/span&gt;
&lt;span class="n"&gt;process_name&lt;/span&gt;&lt;span class="o"&gt;=%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;program_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;StockWeb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;啓動服務：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;brew&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;supervisor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://hoohoo.top/blog/supervisor-instructions-for-use/"&gt;&lt;span class="caps"&gt;SUPERVISOR&lt;/span&gt;&amp;nbsp;介紹與使用方式&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aptro.github.io/server/architecture/2016/06/21/Jupyter-Notebook-Nginx-Setup.html"&gt;Jupyter Notebook and Nginx&amp;nbsp;Setup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.gushiciku.cn/pl/2MVd/zh-tw"&gt;Mac &lt;span class="caps"&gt;OSX&lt;/span&gt; 開機啟動應用&amp;nbsp;(supervisor)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.twblogs.net/a/5d6115a6bd9eee541c32bb6f"&gt;Python Tricks —— 使用 Supervisor 控制 Linux&amp;nbsp;進程&lt;/a&gt;&lt;/p&gt;</content><category term="網路概論"></category><category term="Mac"></category><category term="Supervisor"></category><category term="Nginx"></category></entry><entry><title>Blog發佈到netlify</title><link href="https://blog.richardnote.com/2021/10/git-netlify/" rel="alternate"></link><published>2021-10-05T16:36:00+08:00</published><updated>2021-10-05T16:36:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-05:/2021/10/git-netlify/</id><summary type="html">&lt;p&gt;使用Netlify來部署Pelican的程式&lt;/p&gt;</summary><content type="html">&lt;p&gt;![[Blog發佈到netlify.png]]&lt;/p&gt;
&lt;p&gt;Netlify&amp;nbsp;基本的說明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://blog.alantsai.net/posts/2018/07/migrate-blog-to-ssg-demo-devops-8-netlify-free-static-site-hosting-service"&gt;netlify 超佛心的靜態網站hosting服務 -&amp;nbsp;不只做hosting還有更多&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由 [[部落格建置]] 與 [[部落格建置-套件]] 兩個篇章的設定，已經把Pelican 可以在本機做測試查看了，接下來就要建置部署在網路上，首先就是要買個網域，看來看去還是 Namecheap&amp;nbsp;最便宜，詳細買過程可以參考：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://make9.tw/wordpress/website-server/namecheap-%E7%B6%B2%E5%9D%80%E8%A8%BB%E5%86%8A%E8%B3%BC%E8%B2%B7-dns-%E8%A8%AD%E5%AE%9A%E6%95%99%E5%AD%B8-%E7%B6%B2%E5%9F%9F%E7%B6%81%E5%AE%9A%E4%B8%BB%E6%A9%9F/"&gt;Namecheap 網址註冊購買 &lt;span class="caps"&gt;DNS&lt;/span&gt; 設定教學&amp;nbsp;網域綁定主機&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;https://richardrobot.xyz  一次買兩年才 &lt;span class="caps"&gt;NT&lt;/span&gt;$ 233 ，還蠻便宜，反正只是做Blog隨手記錄&amp;nbsp;買好了網址接下來就是要把GitHub與Netlify綁定在一起參考流程如下Blog：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://michaelabrahamsen.com/posts/pelican-static-site-on-Netlify/"&gt;Pelican static site on&amp;nbsp;Netlify&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;需要注意的是，Blog文章裏面的執行語法  &lt;/p&gt;
&lt;p&gt;Build&amp;nbsp;command&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pelican content -s publishconf.py&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;這個設定了反而不能，會出現錯誤，我的設定&lt;/p&gt;
&lt;p&gt;![[Netlify設定發佈建置.png]]&lt;/p&gt;
&lt;p&gt;另外需要把Netlify提供的Name Server 設定到 Namecheap&amp;nbsp;的DNS設定&lt;/p&gt;
&lt;p&gt;Netlify的設定畫面：&amp;nbsp;![[Netlify設定Domain的畫面.png]]&lt;/p&gt;
&lt;p&gt;然後對應到：&lt;span class="caps"&gt;NAMESERVERS&lt;/span&gt;&amp;nbsp;選CustomDNS&lt;/p&gt;
&lt;p&gt;![[Namecheap設定的畫面.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="Namecheap"></category><category term="Netlify"></category><category term="Git"></category><category term="Pelican"></category></entry><entry><title>Mac重新開機SSH Token失效</title><link href="https://blog.richardnote.com/2021/10/git-ssh-mac-token/" rel="alternate"></link><published>2021-10-05T16:09:00+08:00</published><updated>2021-10-05T16:09:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-05:/2021/10/git-ssh-mac-token/</id><summary type="html">&lt;p&gt;Mac重新開機SSHToken失效問題&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;![[Sourcetree出現Permissiondenied.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;已經加入Github的SSH Token了，再次的PUSH還是會產生&amp;nbsp;[[SourceTree權限問題]]&lt;/p&gt;
&lt;p&gt;查詢問題之後 參考&lt;a href="https://www.twblogs.net/a/5cc1dbe7bd9eee3aed78a30f"&gt; 操作提示 Permission denied, please try again&lt;/a&gt;&amp;nbsp;，裏面的說明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ssh-add 這個命令不是用來永久性的記住你所使用的私鑰的。實際上，它的作用只是把你指定的私鑰添加到 ssh-agent 所管理的一個 session 當中。而 ssh-agent 是一個用於存儲私鑰的臨時性的 session&amp;nbsp;服務，所以每次重啓都會失效，都需要再次執行命令。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;或是設定 &lt;a href="https://mednoter.com/ssh-add-automatically.html"&gt;Mac 重啟後自動ssh-add&amp;nbsp;私鑰&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;後記：如同部落格的文章，重新開機設定自動使用ssh-add會有個問題，當私鑰需要輸入密碼，就會中斷，後續參考&lt;/p&gt;
&lt;p&gt;&lt;a href="https://segmentfault.com/a/1190000039994119"&gt;【踩坑笔记】mac每次重启都需要重新ssh-add&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用Automator來執行Terminal語法：然後設定在開機執行&lt;/p&gt;
&lt;p&gt;![[開機啓用sshadd的語法.png]]&lt;/p&gt;</content><category term="電腦問題"></category><category term="SSH"></category><category term="Git"></category><category term="Mac"></category></entry><entry><title>副檔名command無法執行</title><link href="https://blog.richardnote.com/2021/10/mac-command-permission/" rel="alternate"></link><published>2021-10-01T11:47:00+08:00</published><updated>2021-10-01T11:47:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-01:/2021/10/mac-command-permission/</id><summary type="html">&lt;p&gt;寫好了可以執行的發佈語法，點擊執行卻出現這個&lt;/p&gt;</summary><content type="html">&lt;p&gt;寫好了可以執行的發佈語法，點擊執行卻出現這個&lt;/p&gt;
&lt;p&gt;![[副檔名command無法執行.png]]&lt;/p&gt;
&lt;p&gt;需要另外給予權限：&lt;code&gt;chmod +x batch_notes_script.command&lt;/code&gt;&lt;/p&gt;</content><category term="電腦問題"></category><category term="權限問題"></category><category term="Mac"></category></entry><entry><title>Obsidian筆記同步到Blog排程</title><link href="https://blog.richardnote.com/2021/10/obsidian-to-pelican/" rel="alternate"></link><published>2021-10-01T09:26:00+08:00</published><updated>2021-10-01T09:26:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-01:/2021/10/obsidian-to-pelican/</id><summary type="html">&lt;p&gt;這個記錄着我製作Obsidian筆記同步到blog的語法&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;緣起&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;自從發現[[Obsidian]]這個東西之後，寫作筆記感覺很方便，而且使用[[Markdown]]語法，也剛好想建置Blog網站，用Python的Pelican套件，一樣是用Markdown來產生文章，就覺得兩個東西可以合併，既可以做筆記，又可以寫Blog。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="_2"&gt;想法&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;obsidian的備份機制使用Github來完成，而且有套件可以自動Push ![[obsidian已安裝的第三方外掛.png]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[[Blog發佈到netlify]] 也是用GitHub&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主要把Obsidian的MD檔同步到Pelican的content資料夾，再做一個發佈的程式就完成了&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_3"&gt;流程：&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Obsidian 的筆記寫完之後使用 &lt;code&gt;command + Shift  + P&lt;/code&gt; 快捷鍵Push到GitHub：ObsidianNote。 參考： [[Obsidian快捷鍵設定]]&lt;/li&gt;
&lt;li&gt;複製檔案到如下圖&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;右邊的 ==隨手筆記==資料夾 複製=&amp;gt; ==/Pelican/content 底下==&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;![[顯示同步資料夾.png]]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;複製圖檔&lt;/li&gt;
&lt;li&gt;執行語法來生成頁面 &lt;code&gt;pelican content&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;git commit &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; push&lt;/li&gt;
&lt;/ol&gt;</content><category term="Obsidian"></category><category term="Obsidian"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Pelican說明Metadata</title><link href="https://blog.richardnote.com/2021/09/pelican-metadata/" rel="alternate"></link><published>2021-09-30T14:21:00+08:00</published><updated>2021-09-30T14:21:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-30:/2021/09/pelican-metadata/</id><summary type="html">&lt;p&gt;整理一個表格來方便查看Pelican的Metadata&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;![[2021-10-01_PM4.46.58.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;您還可以在模板中使用自己的元數據鍵（只要它們不與保留的元數據關鍵字衝突）。下表包含保留的元數據關鍵字列表：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align="center"&gt;Metadata&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align="center"&gt;title&lt;/td&gt;
&lt;td&gt;Title of the article or page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;date&lt;/td&gt;
&lt;td&gt;Publication date (e.g., &lt;span class="caps"&gt;YYYY&lt;/span&gt;-&lt;span class="caps"&gt;MM&lt;/span&gt;-&lt;span class="caps"&gt;DD&lt;/span&gt; &lt;span class="caps"&gt;HH&lt;/span&gt;:&lt;span class="caps"&gt;SS&lt;/span&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;modified&lt;/td&gt;
&lt;td&gt;Modification date (e.g., &lt;span class="caps"&gt;YYYY&lt;/span&gt;-&lt;span class="caps"&gt;MM&lt;/span&gt;-&lt;span class="caps"&gt;DD&lt;/span&gt; &lt;span class="caps"&gt;HH&lt;/span&gt;:&lt;span class="caps"&gt;SS&lt;/span&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;tags&lt;/td&gt;
&lt;td&gt;Content tags, separated by commas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;keywords&lt;/td&gt;
&lt;td&gt;Content keywords, separated by commas (&lt;span class="caps"&gt;HTML&lt;/span&gt; content only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;category&lt;/td&gt;
&lt;td&gt;Content category (one only — not multiple)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;slug&lt;/td&gt;
&lt;td&gt;Identifier used in URLs and translations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;author&lt;/td&gt;
&lt;td&gt;Content author, when there is only one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;authors&lt;/td&gt;
&lt;td&gt;Content authors, when there are multiple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;summary&lt;/td&gt;
&lt;td&gt;Brief description of content for index pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;lang&lt;/td&gt;
&lt;td&gt;Content language &lt;span class="caps"&gt;ID&lt;/span&gt; (en, fr, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;translation&lt;/td&gt;
&lt;td&gt;If content is a translation of another (true or false)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;status&lt;/td&gt;
&lt;td&gt;Content status: draft, hidden, or published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;template&lt;/td&gt;
&lt;td&gt;Name of template to use to generate content (without extension)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;save_as&lt;/td&gt;
&lt;td&gt;Save content to this relative file path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;url&lt;/td&gt;
&lt;td&gt;&lt;span class="caps"&gt;URL&lt;/span&gt; to use for this article/page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>SourceTree權限問題</title><link href="https://blog.richardnote.com/2021/09/git-sourcetree-permission/" rel="alternate"></link><published>2021-09-29T17:58:00+08:00</published><updated>2021-09-29T17:58:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-29:/2021/09/git-sourcetree-permission/</id><summary type="html">&lt;p&gt;Sourcetree出現Permission denied&amp;nbsp;(publickey)&lt;/p&gt;</summary><content type="html">&lt;h3 id="sourcetreepermission-denied-publickey"&gt;Sourcetree出現Permission denied (publickey)&lt;a class="headerlink" href="#sourcetreepermission-denied-publickey" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;![[Sourcetree出現Permissiondenied.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;這個問題的產生可能是程式問題，已經透過SourceTree的UI界面功能去產生SSH的KEY
做法來源[[Mac 上改變 Git 認證模式]]&amp;nbsp;，也已經至GitHub去註冊KEY&lt;/p&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210929180241.png]]&lt;/p&gt;
&lt;p&gt;Google以後參考資料部落格：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://medium.com/@wade30191/macos%E6%9B%B4%E6%96%B0%E5%BE%8C%E4%BD%BF%E7%94%A8sourcetree%E5%87%BA%E7%8F%BEpermission-denied-publickey-c226a85c0a3a"&gt;MacOS更新後使用Sourcetree出現Permission denied&amp;nbsp;(publickey)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;就去找出當初用GitHub產生的PrivateKey在哪如下圖左紅框，就執行一下以下語法就可以了&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210929180643.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;==語法：==&lt;/p&gt;
&lt;p&gt;執行新增&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jarvis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zheng&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;GitHub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;檢查語法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ssh&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="nd"&gt;@github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="網路概論"></category><category term="Git"></category><category term="SourceTree"></category></entry><entry><title>部落格建置-套件</title><link href="https://blog.richardnote.com/2021/09/pelican-plugins/" rel="alternate"></link><published>2021-09-29T15:50:00+08:00</published><updated>2021-09-29T15:50:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-29:/2021/09/pelican-plugins/</id><summary type="html">&lt;p&gt;要使用Pelican的外掛套件，目前套件的來源有兩種&lt;/p&gt;</summary><content type="html">&lt;p&gt;要使用Pelican的外掛套件，目前套件的來源有兩種：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在命名空間之下的Git，&lt;a href="https://github.com/pelican-plugins"&gt;新版pelican-plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;舊版的套件集合的Git，&lt;a href="https://github.com/getpelican/pelican-plugins"&gt;舊版pelican-plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;導入套件的方式有兩種：&amp;nbsp;如果您的插件不在可導入路徑中，您可以通過PLUGIN_PATHS設置指定路徑列表。如以下示例所示，PLUGIN_PATHS列表中的路徑可以是相對於設置文件的絕對路徑或相對路徑：&lt;/p&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210929155953.png]]&lt;/p&gt;
&lt;p&gt;若是沒有依照設定的套件名稱放置程式會出現錯誤訊息：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Pelican&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zheng&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;zhengruichangdeMac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mini&lt;/span&gt; &lt;span class="nx"&gt;Pelican&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;pelican&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;
&lt;span class="nx"&gt;WARNING&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;usage&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;CATEGORY_FEED_ATOM&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;deprecated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;instead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;ERROR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cannot&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt; &lt;span class="sb"&gt;`related_posts`&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Cannot&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt; &lt;span class="sb"&gt;`related_posts`&lt;/span&gt;
&lt;span class="nx"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Processed&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;drafts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;draft&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3 id="_1"&gt;總結&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;套件的使用，在命名空間下的，要執行安裝語法，會直接搜尋環境下的套件程式，若是用舊版的，要去舊版git&amp;nbsp;去clone下來，並且對照名稱放程式資料夾在/pelican-plugins&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>部落格建置</title><link href="https://blog.richardnote.com/2021/09/pelican/" rel="alternate"></link><published>2021-09-28T17:44:00+08:00</published><updated>2021-09-28T17:44:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-28:/2021/09/pelican/</id><summary type="html">&lt;p&gt;用Pelican套件建置部落格在GitHub Pages&amp;nbsp;上，首先需要安裝Pelican的環境&lt;/p&gt;</summary><content type="html">&lt;h4 id="pelicangithub-pages-pelican"&gt;用Pelican套件建置部落格在GitHub Pages 上，首先需要安裝Pelican的環境&lt;a class="headerlink" href="#pelicangithub-pages-pelican" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;建立python的虛擬環境
&lt;code&gt;conda create -n Pelican&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;啓動虛擬環境
&lt;code&gt;conda activate Pelican&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;CD&lt;/span&gt;&amp;nbsp;到新開的資料夾，&lt;/p&gt;
&lt;p&gt;當初已經在GitHub上建立好了Repository，所以就在本機建立資料夾然後Clone，在Pelican資料夾下，需要安裝pelican的相關套件，需要創建一個requirements.txt文件&lt;/p&gt;
&lt;p&gt;&lt;code&gt;touch requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接下來安裝所有套件：
&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;若是還沒建立好預設開始環境需要執行以下語法，Pelican會建立基本的程式與資料夾，若是執行以下語法會需要回答一些預設環境的設定值
&lt;code&gt;pelican-quickstart&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;資料夾架構如下
![[Pasted image 20210929144934.png]]&amp;nbsp;每個文件的用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;content/ -&amp;nbsp;存儲所有網站內容的目錄&lt;/li&gt;
&lt;li&gt;task.py -&amp;nbsp;幫助我們自動化網站生成和發布的腳本&lt;/li&gt;
&lt;li&gt;output/ - 存儲生成的靜態網站的 &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;文件的目錄&lt;/li&gt;
&lt;li&gt;pelicanconf.py -&amp;nbsp;包含網站所有配置的文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="_1"&gt;生成網站&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;此語法會在 output/ 目錄產生所有html 的頁面
&lt;code&gt;pelican content&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;此語法會產生一個臨時的站臺 127.0.0.1:8000 可以預覽頁面
&lt;code&gt;pelican --listen&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看外掛套件清單：
&lt;code&gt;pelican-plugins&lt;/code&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Markdown-插入圖片</title><link href="https://blog.richardnote.com/2021/09/markdown-cha-ru-tu-pian/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-cha-ru-tu-pian/</id><summary type="html">&lt;p&gt;顯示插入圖片&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png &amp;quot;這個文字會滑鼠滑上會出現POPup&amp;quot;)&lt;/span&gt;


&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;這裡是要寫圖片說明&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//這個是要填圖片路徑.jpg)&lt;/span&gt;


&lt;span class="err"&gt;使用代碼重複利用相同圖片方式：&lt;/span&gt;

&lt;span class="err"&gt;最近在看的新書：&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Google教我的101個工作最佳化&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;google101&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="err"&gt;最近在看的新書：&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Google教我的101個工作最佳化&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;google101&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="err"&gt;最近在看的新書：&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Google教我的101個工作最佳化&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;google101&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;google101&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/058/32/0010583256.jpg&amp;amp;v=51751f70&amp;amp;w=348&amp;amp;h=348 &amp;quot;Google教我的101個工作最佳化&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;實例展示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="alt text" src="https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png" title="這個文字會滑鼠滑上會出現POPup" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="企業正在進行AI前導測試，並將人工智慧投入生產。以下是業界菁英對AI的投資方向，且已見到初步成果" src="https://www.cio.com.tw/wp-content/uploads/1200-AdobeStock_178319041-750x394.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;最近在看的新書：&lt;img alt="Google教我的101個工作最佳化" src="https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/058/32/0010583256.jpg&amp;amp;v=51751f70&amp;amp;w=348&amp;amp;h=348" title="Google教我的101個工作最佳化" /&gt;&lt;/p&gt;
&lt;p&gt;最近在看的新書：&lt;img alt="Google教我的101個工作最佳化" src="https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/058/32/0010583256.jpg&amp;amp;v=51751f70&amp;amp;w=348&amp;amp;h=348" title="Google教我的101個工作最佳化" /&gt;&lt;/p&gt;
&lt;p&gt;最近在看的新書：&lt;img alt="Google教我的101個工作最佳化" src="https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/058/32/0010583256.jpg&amp;amp;v=51751f70&amp;amp;w=348&amp;amp;h=348" title="Google教我的101個工作最佳化" /&gt;&lt;/p&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-程式代碼或語法高亮</title><link href="https://blog.richardnote.com/2021/09/markdown-cheng-shi-dai-ma-huo-yu-fa-gao-liang/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-cheng-shi-dai-ma-huo-yu-fa-gao-liang/</id><summary type="html">&lt;p&gt;顯示程式代碼或語法高亮&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;直接展示：每個三個` 符號 後面直接寫程式語言名稱如：sql C# java python&amp;nbsp;等等的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;JavaScript syntax highlighting&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Python syntax highlighting&amp;quot;&lt;/span&gt;  
&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;No language indicated, so no syntax highlighting.  
But let&amp;#39;s throw in a &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;tag&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;.  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-連結設定</title><link href="https://blog.richardnote.com/2021/09/markdown-lian-jie-she-ding/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-lian-jie-she-ding/</id><summary type="html">&lt;p&gt;顯示連結設定&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tw&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;


&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;這是一個帶有標題的行內連結&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;Google&amp;#39;s Homepage&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;中文版的&lt;/span&gt;&lt;span class="n"&gt;Markdown語法說明&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



&lt;span class="err"&gt;使用代碼去重複使用：&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;來看看這個網址&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;我是網址&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;去看看這個網址&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;我是網址&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;檢查這個網址&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;我是網址&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;我是網址&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tw&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;實例展示：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://markdown.tw"&gt;http://markdown.tw&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.google.com" title="Google's Homepage"&gt;這是一個帶有標題的行內連結&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://markdown.tw"&gt;中文版的Markdown語法說明&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.google.com.tw"&gt;來看看這個網址&lt;/a&gt;
&lt;a href="https://www.google.com.tw"&gt;去看看這個網址&lt;/a&gt;
&lt;a href="https://www.google.com.tw"&gt;檢查這個網址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="alt text" src="https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png" title="Logo 標題文字範例一" /&gt;&lt;/p&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-其他的符號</title><link href="https://blog.richardnote.com/2021/09/markdown-qi-ta-de-fu-hao/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-qi-ta-de-fu-hao/</id><summary type="html">&lt;p&gt;顯示其他的符號&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;[ ]&amp;nbsp;代辦事項  &lt;/li&gt;
&lt;li&gt;[x]&amp;nbsp;已完成事項&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;跳脫字元
加上反引號&amp;nbsp;\&lt;/p&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-水平分隔線</title><link href="https://blog.richardnote.com/2021/09/markdown-shui-ping-fen-ge-xian/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-shui-ping-fen-ge-xian/</id><summary type="html">&lt;p&gt;顯示水平分隔線&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;語法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;---短橫線（Hyphens）&lt;/span&gt;

&lt;span class="o"&gt;***&lt;/span&gt;&lt;span class="err"&gt;半形星號（&lt;/span&gt;&lt;span class="n"&gt;Asterisks&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;

&lt;span class="n"&gt;___下底線&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;Underscores&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-文字變化</title><link href="https://blog.richardnote.com/2021/09/markdown-wen-zi-bian-hua/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-wen-zi-bian-hua/</id><summary type="html">&lt;p&gt;顯示文字變化&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;asterisks&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="err"&gt;斜體&lt;/span&gt;  
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;asterisks&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="err"&gt;粗體&lt;/span&gt;

&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="err"&gt;螢光強調&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;實際展示：&lt;/p&gt;
&lt;p&gt;&lt;em&gt;我是斜體字&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我是粗體字測試&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;==螢光強調==&lt;/p&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-項目清單</title><link href="https://blog.richardnote.com/2021/09/markdown-xiang-mu-qing-dan/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-xiang-mu-qing-dan/</id><summary type="html">&lt;p&gt;顯示清單的語法&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;* 無序列表一 //可以使用星號建立無序清單  &lt;/span&gt;
&lt;span class="err"&gt;- 無序列表二 //或是短橫線（負號）  &lt;/span&gt;
&lt;span class="err"&gt;+ 無序列表三 //使用半形加號也可以  &lt;/span&gt;
&lt;span class="err"&gt;1. 有序列表一  &lt;/span&gt;
&lt;span class="err"&gt;2. 有序列表二  &lt;/span&gt;
&lt;span class="err"&gt;3. 有序列表三&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;實際展示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;無序列表一&lt;/li&gt;
&lt;li&gt;無序列表二&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;無序列表三&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一樣的無序列表用負號&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;一樣的無序列表用負號&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一樣的無序列表用負號&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一樣的無序列表用加號&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;一樣的無序列表用加號&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一樣的無序列表用加號&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有序號列表一&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;有序號列表二&lt;/li&gt;
&lt;li&gt;有序號列表三&lt;/li&gt;
&lt;/ul&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-語法學習</title><link href="https://blog.richardnote.com/2021/09/markdown-yu-fa-xue-xi/" rel="alternate"></link><published>2021-09-16T17:59:00+08:00</published><updated>2021-09-16T17:59:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-yu-fa-xue-xi/</id><summary type="html">&lt;p&gt;Markdown 語言在 2004 由約翰·格魯伯（英語：John Gruber）創建Markdown&amp;nbsp;是一種輕量級標記語言，它允許人們使用易讀易寫的純文本格式編寫文檔&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;Markdown 語言在 2004 由約翰·格魯伯（英語：John Gruber）創建。Markdown&amp;nbsp;是一種輕量級標記語言，它允許人們使用易讀易寫的純文本格式編寫文檔。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://markdown.tw/"&gt;Markdown&lt;/a&gt;是一種簡易的標記語言，能讓我們在最短的時間裡製作一份易讀易懂的文字檔案，當有需要輸出到網站時，也能使用許多線上轉換網站或軟體，將Markdown格式的內容轉換成HTML格式，瞬間由文字格式變身美觀的網頁格式。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;[[分段標題]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以一到六個井字表示標題一至標題六&lt;code&gt;（&amp;lt;h1&amp;gt;到&amp;lt;h6&amp;gt;）&lt;/code&gt;，亦即井號越少顯示的字體越大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[項目清單]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;列舉式的項目清單是很常用的表達語法，在HTML網頁的定義裡主要有兩種：有順序編號的&lt;code&gt;（&amp;lt;ol&amp;gt;+&amp;lt;li&amp;gt;）&lt;/code&gt;和沒有順序編號的 &lt;code&gt;（&amp;lt;ul&amp;gt;+&amp;lt;li&amp;gt;）&lt;/code&gt;，Markdown的表示方法很簡單:&lt;/p&gt;
&lt;p&gt;1.有順序編號的清單：每列開頭是「數字.一個空白」&amp;nbsp;2.沒有順序編號的清單：就是以項目符號開頭的清單，以「*一個空白」或「減號一個空白」來表示
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[文字變化]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一段文字裡需要特別注意或要有不同變化時&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[連結設定]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;快速超連結：只要把超連結用「&amp;lt;」、「&amp;gt;」括住即可，被括住的網址會形成可點擊的超連結&lt;/p&gt;
&lt;p&gt;完整超連結：上面快速超連結直接用網址來顯示，我們可以用&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[顯示文字](http://jdev.tw/blog/3504/test)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;的語法在網頁顯示指定的文字與其使用的超連結。Markdown插入超連結的語法很簡單，但無法指示開啟在新視窗或新分頁。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[插入圖片]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;比照超連結的寫法再於開頭加上&lt;code&gt;半形驚嘆號&lt;/code&gt;就可以了
語法： &lt;code&gt;![顯示文字](圖片網址)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[程式代碼或語法高亮]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在一般文字中直接用 &lt;code&gt;這個樣子&lt;/code&gt; ，若是要包整段的要三個 &amp;#8220;`&amp;nbsp;符號前後包起來&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;引言&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用一個 小於符號  &lt;code&gt;&amp;gt;&lt;/code&gt;  放在最前面就可以外面有框線包起來的樣子&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;行內HTML&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;因為 Markdown 本來就預設要轉換成 &lt;span class="caps"&gt;HTML&lt;/span&gt; 網頁格式，所以你當然可以直接寫入正確的 &lt;span class="caps"&gt;HTML&lt;/span&gt; 代碼   &lt;code&gt;&amp;lt;H1&amp;gt;ttt&amp;lt;/H1&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[水平分隔線]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;三個或三個以上的符號，必須在獨立的一行，前後不能有其他文字。&lt;/p&gt;
&lt;p&gt;&amp;#8212;-短橫線（Hyphens）&lt;/p&gt;
&lt;p&gt;***半形星號（Asterisks）&lt;/p&gt;
&lt;p&gt;___下底線（Underscores）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[[其他的符號]]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;剩下少用的東西有 &lt;code&gt;代辦事項&lt;/code&gt;  &lt;code&gt;列表縮進&lt;/code&gt; &lt;code&gt;跳脫字元&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Markdown-分段標題</title><link href="https://blog.richardnote.com/2021/09/markdown-fen-duan-biao-ti/" rel="alternate"></link><published>2021-09-16T17:58:00+08:00</published><updated>2021-09-16T17:58:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/markdown-fen-duan-biao-ti/</id><summary type="html">&lt;p&gt;顯示分段標題&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;h1 id="_1"&gt;標題&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;`&amp;#8217;語法顯示&amp;#8217;&lt;/p&gt;
&lt;h1 id="h1"&gt;H1&lt;a class="headerlink" href="#h1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="h2"&gt;H2&lt;a class="headerlink" href="#h2" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="h3"&gt;H3&lt;a class="headerlink" href="#h3" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="h4"&gt;H4&lt;a class="headerlink" href="#h4" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;h5 id="h5"&gt;H5&lt;a class="headerlink" href="#h5" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h5&gt;
&lt;h6 id="h6"&gt;H6&lt;a class="headerlink" href="#h6" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h6&gt;
&lt;p&gt;最常使用的 H1 與 H2&amp;nbsp;標題，還有更鮮明的另一種寫法：&lt;/p&gt;
&lt;h1 id="alt-h1"&gt;Alt-H1&lt;a class="headerlink" href="#alt-h1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="alt-h2"&gt;Alt-H2&lt;a class="headerlink" href="#alt-h2" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;`&lt;/p&gt;
&lt;p&gt;實際展示：&lt;/p&gt;
&lt;h1 id="_2"&gt;標題&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;h6 id="_3"&gt;標題&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h6&gt;
&lt;h1 id="_4"&gt;鮮明的標題&lt;a class="headerlink" href="#_4" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="_5"&gt;鮮明的標題&lt;a class="headerlink" href="#_5" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;</content><category term="Markdown"></category><category term="Markdown"></category></entry><entry><title>Obsidian 使用 Git 跨平台同步</title><link href="https://blog.richardnote.com/2021/09/git-obsidian/" rel="alternate"></link><published>2021-09-16T17:55:00+08:00</published><updated>2021-09-16T17:55:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/git-obsidian/</id><summary type="html">&lt;p&gt;使用Obsidian搭配Git達成可以跨越系統的同步&lt;/p&gt;</summary><content type="html">&lt;p&gt;第一步&amp;nbsp;先在Windows本機的建立一個資料夾，是拿來開啟Obsidian的Vault&lt;/p&gt;
&lt;p&gt;![[Pasted image 20210914152609.png]]
像上面的資料路徑我新開了一個 ObsidianNote資料夾，然後Obisdian設定這個資料夾就會有一些設定檔
![[Pasted image&amp;nbsp;20210914152831.png]]&lt;/p&gt;
&lt;p&gt;第二步&amp;nbsp;在GitHub建立一個repository，然後取名同樣的名稱ObsidianNote&lt;/p&gt;
&lt;p&gt;第三步
開啟CMD&amp;nbsp;然後CD至剛剛的資料夾，接下來就是執行GitHub上面的初始化語法&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;
&lt;code&gt;git commit -m "first commit"&lt;/code&gt;
&lt;code&gt;git remote add origin https://github.com/TernenceZheng/ObsidianNote.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210914153508.png]]&lt;/p&gt;
&lt;p&gt;第四步
安裝第三方外掛套件 Obsidian Git
![[Pasted image&amp;nbsp;20210914161351.png]]&lt;/p&gt;
&lt;p&gt;安裝及啟用後，左方將出現 Obsidian Git&amp;nbsp;的設定，我有以下的建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;將 Vault 備份時間改為 5 分鐘 (Backup Interval:&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;每次打開軟件也從 Github Pull 所有的變更 (Pull updates on startup: &lt;span class="caps"&gt;ON&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Commit Message 增加電腦名稱以便識別 (Commit message:&amp;nbsp;開首加電腦名稱）&lt;/li&gt;
&lt;li&gt;以及最重要的關掉 Disable Push（Disable Push: &lt;span class="caps"&gt;OFF&lt;/span&gt;)，才會自動把所有 Commit 推送到 Github&amp;nbsp;上，讓其他裝置可以同步。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;參考鏈接：&lt;a href="https://notes.desktopofsamuel.com/posts/Obsidian%E4%B8%8A%E6%89%8B%E5%8F%8A%E4%BD%BF%E7%94%A8Git%E8%B7%A8%E5%B9%B3%E5%8F%B0%E5%90%8C%E6%AD%A5/"&gt;Obsidian上手及使用Git跨平台同步&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外的手機版本同步參考：&lt;a href="https://forum.obsidian.md/t/mobile-setting-up-ios-git-based-syncing-with-mobile-app-using-working-copy/16499"&gt;[移動] 設置 iOS 與移動應用程序基於 git&amp;nbsp;的同步（使用工作副本）&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Obsidian"></category><category term="Git"></category></entry><entry><title>Mac 上改變 Git 認證模式</title><link href="https://blog.richardnote.com/2021/09/git-mac-add-token/" rel="alternate"></link><published>2021-09-16T17:53:00+08:00</published><updated>2021-09-16T17:53:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/git-mac-add-token/</id><summary type="html">&lt;p&gt;Mac 上改變 Git&amp;nbsp;認證模式&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;2021/09/14 今天在mac 上面在 git clone&amp;nbsp;https://github.com/TernenceZheng/ObsidianNote.git&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;![[Mac上改變Git認證模式.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;結果我的mac顯示無法用使用者帳號密碼去登入驗證&lt;/p&gt;
&lt;p&gt;&lt;code&gt;'Mac上面錯誤訊息'
Cloning into 'ObsidianNote'...
Username for 'https://github.com': andy711023@gmail.com
Password for 'https://andy711023@gmail.com@github.com': 
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/TernenceZheng/ObsidianNote.git/'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;看了文章原來要去用GitHub的Token驗證方式才可以，舊的帳號密碼已經不行了，下面是Github產生的Token
![[Pasted image&amp;nbsp;20210914164331.png]]&lt;/p&gt;
&lt;p&gt;把拿到的Token註冊在MacOS的鑰匙圈如下圖&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;![[Pic2021-09-144.54.10.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;就完成Token的驗證註冊，然後git&amp;nbsp;clone就OK了&lt;/p&gt;
&lt;p&gt;參考資料：&lt;a href="https://myctw.github.io/post/bd72.html"&gt;Mac 上改變 Git&amp;nbsp;認證模式&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相關主題：
[[Obsidian 使用 Git 跨平台同步]]&amp;nbsp;[[SourceTree權限問題]]&lt;/p&gt;</content><category term="網路概論"></category><category term="Git"></category><category term="Mac"></category></entry><entry><title>Obsidian快捷鍵設定</title><link href="https://blog.richardnote.com/2021/09/obsidiankuai-jie-jian-she-ding/" rel="alternate"></link><published>2021-09-16T17:40:00+08:00</published><updated>2021-09-16T17:40:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/obsidiankuai-jie-jian-she-ding/</id><summary type="html">&lt;p&gt;Obsidian快捷鍵設定&lt;/p&gt;</summary><content type="html">&lt;h1 id="obsidian"&gt;[[Obsidian]] 快捷鍵設定&lt;a class="headerlink" href="#obsidian" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;參考網址：&lt;a href="https://medium.com/pm%E7%9A%84%E7%94%9F%E7%94%A2%E5%8A%9B%E5%B7%A5%E5%85%B7%E7%AE%B1/obsidian-%E4%BD%BF%E7%94%A8%E6%95%99%E5%AD%B8-%E7%AD%86%E8%A8%98%E7%AF%87-08-%E5%80%8D%E9%80%9F%E6%8F%90%E5%8D%87%E4%BD%A0%E7%9A%84%E6%93%8D%E4%BD%9C%E9%80%9F%E5%BA%A6-14-%E5%80%8B-obsidian-%E5%BF%AB%E6%8D%B7%E9%8D%B5%E8%A8%AD%E5%AE%9A%E5%BB%BA%E8%AD%B0-adc2d025c6d1"&gt;14個Obsidian快捷鍵設定建議&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;記錄目前最常使用的快捷鍵：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能：快速插入模板筆記  &lt;code&gt;cmd + L&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;功能：立即執行Git的PUSH更新 &lt;code&gt;cmd + Shift + P&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Obsidian"></category><category term="Obsidian"></category></entry><entry><title>Obsidian</title><link href="https://blog.richardnote.com/2021/09/obsidian/" rel="alternate"></link><published>2021-09-16T15:54:00+08:00</published><updated>2021-09-16T15:54:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/obsidian/</id><summary type="html">&lt;p&gt;直接引用Youtube影片說明&lt;/p&gt;</summary><content type="html">&lt;p&gt;參考網址：
筆記類別：#心得&amp;nbsp;主題：[[Obsidian]]&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=0s"&gt;00:00&lt;/a&gt;&amp;nbsp;開場白 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=73s"&gt;01:13&lt;/a&gt;&amp;nbsp;要點一：捕捉生活中的靈感與想法 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=200s"&gt;03:20&lt;/a&gt;&amp;nbsp;要點二：用自己的話寫筆記 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=259s"&gt;04:19&lt;/a&gt;&amp;nbsp;要點三：引用內容要標注出處 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=302s"&gt;05:02&lt;/a&gt;&amp;nbsp;要點四：建立筆記之間的連結 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=398s"&gt;06:38&lt;/a&gt;&amp;nbsp;要點五：每則筆記必須簡明扼要 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=446s"&gt;07:26&lt;/a&gt;&amp;nbsp;筆記關聯圖 &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Egj_DdGUIDI&amp;amp;list=RDCMUCdEpz2A4DzV__4C1x2quKLw&amp;amp;index=1&amp;amp;t=505s"&gt;08:25&lt;/a&gt; Obsidian&amp;nbsp;的外掛簡介&lt;/li&gt;
&lt;/ul&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/Egj_DdGUIDI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;</content><category term="Obsidian"></category><category term="Obsidian"></category></entry><entry><title>使用vncserver建立遠端管理GCP與內容管理系統建置</title><link href="https://blog.richardnote.com/2020/12/vncserver-gcp/" rel="alternate"></link><published>2020-12-01T15:57:00+08:00</published><updated>2021-12-01T15:57:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2020-12-01:/2020/12/vncserver-gcp/</id><summary type="html">&lt;p&gt;使用vncserver建立遠端管理GCP與架設內容管理系統站臺&lt;/p&gt;</summary><content type="html">
&lt;p&gt;這篇文章是從頭建立起GCP網站，與遠端連線的方法
1. 使用VNC Server來遠端桌面連線，因為有許多需要修改設定檔需要遠端執行
2. 站臺的建立方式WebServer是用Nginx+Gunicorn ，Python的站臺程式用WagtailCMS&lt;/p&gt;
&lt;h2 id="vnc-servergcp"&gt;&lt;span class="caps"&gt;VNC&lt;/span&gt; Server建立可遠端桌面連線GCP&lt;a class="headerlink" href="#vnc-servergcp" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;p&gt;首先，先在GCP建立Compute Engine的VM執行個體，VM的執行個體系統選擇Ubuntu，再將外部IP改為靜態IP&lt;/p&gt;
&lt;p&gt;![[VM設定靜態IP.png]] ![[VM設定靜態IP2.png]]&lt;/p&gt;
&lt;p&gt;使用平臺提供的瀏覽器Terminal&lt;/p&gt;
&lt;p&gt;![[使用平臺提供的瀏覽器Terminal.png]] ![[使用平臺提供的瀏覽器Terminal2.png]]&lt;/p&gt;
&lt;p&gt;安裝一些必要的套件，並且執行 vnc4server 執行語法:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get upgrade&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install ubuntu-desktop gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install vnc4server&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vnc4server&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;![[安裝與執行vnc4server.png]]&lt;/p&gt;
&lt;h3 id="vncxstartup"&gt;修改~/.vnc/xstartup 的設定&lt;a class="headerlink" href="#vncxstartup" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;輸入語法：
&lt;code&gt;sudo vim .vnc/xstartup&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;進入如下畫面： 畫面是使用ubuntu的內建vim編輯器&lt;/p&gt;
&lt;p&gt;![[畫面是使用ubuntu的內建vim編輯器.png]]&lt;/p&gt;
&lt;p&gt;按 I 進入編輯模式 貼上四行語法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;gnome&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;panel&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
&lt;span class="n"&gt;gnome&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;daemon&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
&lt;span class="n"&gt;metacity&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
&lt;span class="n"&gt;nautilus&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;再輸入 :wq 儲存退出&lt;/p&gt;
&lt;p&gt;輸入語法
&lt;code&gt;vncserver -kill :1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vncserver :1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;以上完成vncserver建立，可遠端桌面連線了 &lt;/p&gt;
&lt;p&gt;GCP需要開啟防火牆 指定 &lt;span class="caps"&gt;PORT&lt;/span&gt; 5901&lt;/p&gt;
&lt;p&gt;![[GCP需要開啟防火牆.png]]&lt;/p&gt;
&lt;h3 id="realvnc-viewer"&gt;下載RealVNC Viewer&lt;a class="headerlink" href="#realvnc-viewer" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;輸入 35.229.134.113:5901 連線，這個連線IP就是當初建立VM的外部靜態IP&lt;/p&gt;
&lt;p&gt;![[下載RealVNC.png]] ![[下載RealVNC2.png]]&lt;/p&gt;
&lt;p&gt;可遠端桌面連線是方便以後程式建置時，資料架構查看或上傳程式方便&lt;/p&gt;
&lt;h2 id="google-cloudubuntu-postgresnginxgunicorndjango"&gt;如何在Google Cloud中的Ubuntu 上使用Postgres，Nginx和Gunicorn設置Django&lt;a class="headerlink" href="#google-cloudubuntu-postgresnginxgunicorndjango" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;p&gt;前置準備：
1. 您的Compute Engine實例正在運行，請參閱設置Compute Engine實例。
2. 域名指向您的虛擬機。（此Domain我已先設定FreeDNS：gcp.mooo.com 暫時的設定，到時候申請好正式的Domain再修改）
3. 有關設置Cloud DNS的信息，請參閱為您的域設置Google Cloud &lt;span class="caps"&gt;DNS&lt;/span&gt;。&lt;/p&gt;
&lt;p&gt;在一樣剛剛的GCP Terminal安裝以下套件&lt;/p&gt;
&lt;p&gt;執行語法：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt update&lt;/code&gt;
&lt;code&gt;sudo apt install python3-pip python3-dev libpq-dev postgresql-contrib nginx curl&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;![[安裝套件跟postgresql.png]]&lt;/p&gt;
&lt;p&gt;如下圖，在GCP的操作功能上找SQL，並且產生Cloud SQL執行個體&lt;/p&gt;
&lt;p&gt;![[建立GCP的SQL資料庫.png]]&lt;/p&gt;
&lt;p&gt;位置區域要跟VM的位置區域一樣&lt;/p&gt;
&lt;p&gt;![[位置區域要跟VM的位置區域一樣.png]]&lt;/p&gt;
&lt;p&gt;建立SQL後，下面顯示的公開IP是到時候程式Django站臺連線需要&lt;/p&gt;
&lt;p&gt;![[建立SQL後下面顯示的公開IP是到時候程式連線需要.png]]&lt;/p&gt;
&lt;p&gt;編輯連線設定：設定只有VM的IP可以連線，填入GCP的靜態外部IP&lt;/p&gt;
&lt;p&gt;![[編輯連線設定設定只有VM的IP可以連線.png]]&lt;/p&gt;
&lt;p&gt;上面建立好資料庫後，開始建立VM上面Django的專案&lt;/p&gt;
&lt;h2 id="vmwagtailcms"&gt;建立VM上面WagtailCMS的專案&lt;a class="headerlink" href="#vmwagtailcms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;p&gt;接下來就開始是安裝與建立內容管理系統的部分，與GCP的設定大部分已完成。
關於內容管理系統的試用分享可查看： [[內容管理系統CMS]]&lt;/p&gt;
&lt;p&gt;建構的流程
1. 建立Python的虛擬環境
2. 安裝套裝程式:Django gunicorn coderedcms 
3. 設定連線字串
4. 執行 python manage.py migrate 初始化
5. 建立Gunicorn 連接起程式
6. 設定Nginx的設定檔&lt;/p&gt;
&lt;h3 id="python"&gt;建立Python的虛擬環境&lt;a class="headerlink" href="#python" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;執行語法：（下面的語法含義可看文章說明）
安裝虛擬環境
&lt;code&gt;sudo -H pip3 install --upgrade pip&lt;/code&gt;
&lt;code&gt;sudo -H pip3 install virtualenv&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;建立名為WagtailDir 資料夾，並且創建虛擬環境，切換環境
&lt;code&gt;mkdir ~/WagtailDir&lt;/code&gt;
&lt;code&gt;cd ~/WagtailDir&lt;/code&gt;
&lt;code&gt;virtualenv WagtailEnv&lt;/code&gt;
&lt;code&gt;source WagtailEnv/bin/activate&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;下圖是建立資料夾與python的虛擬環境&lt;/p&gt;
&lt;p&gt;![[建立資料夾與python的虛擬環境.png]]&lt;/p&gt;
&lt;h3 id="django-gunicorn-coderedcms"&gt;安裝套裝程式:Django gunicorn coderedcms&lt;a class="headerlink" href="#django-gunicorn-coderedcms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;執行語法
&lt;code&gt;pip install django gunicorn psycopg2-binary&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pip install coderedcms&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;coderedcms start WagtailProject --sitename "網站名稱"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;上面是建立Django專案的語法，還有CodeRed &lt;span class="caps"&gt;CMS&lt;/span&gt; 的套件，從VNC Viewer可看到資料夾&lt;/p&gt;
&lt;p&gt;![[還有CodeRed &lt;span class="caps"&gt;CMS&lt;/span&gt; 的套從VNC Viewer可看到資料夾.png]]
![[還有CodeRed &lt;span class="caps"&gt;CMS&lt;/span&gt; 的套從VNC Viewer可看到資料夾2.png]]&lt;/p&gt;
&lt;h3 id="_1"&gt;設定連線字串&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;修改連線字串：連線字串在 /settings/base.py&lt;/p&gt;
&lt;p&gt;![[修改連線字串連線字串在basepy.png]]&lt;/p&gt;
&lt;p&gt;連線字串的修改相關名稱設定可參考Django的連線設定，連線字串的使用者與密碼就是前面在GCP設定的&lt;/p&gt;
&lt;p&gt;![[連線字串與使用者是上面在GCE設定的.png]]&lt;/p&gt;
&lt;p&gt;上面連線字串修改好是連線遠端SQL的資料庫後，接下來的語法執行就開始建立資料庫的Table與 Schema&lt;/p&gt;
&lt;h3 id="python-managepy-migrate"&gt;執行 python manage.py migrate 初始化&lt;a class="headerlink" href="#python-managepy-migrate" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;![[開始建立資料庫的Table與Schema.png]]&lt;/p&gt;
&lt;p&gt;執行語法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;WagtailProject&lt;/span&gt;
&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;py&lt;/span&gt; &lt;span class="n"&gt;migrate&lt;/span&gt;
&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;py&lt;/span&gt; &lt;span class="n"&gt;makemigrations&lt;/span&gt;
&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;py&lt;/span&gt; &lt;span class="n"&gt;createsuperuser&lt;/span&gt;
&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;py&lt;/span&gt; &lt;span class="n"&gt;runserver&lt;/span&gt;
&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;py&lt;/span&gt; &lt;span class="n"&gt;collectstatic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;看到以下畫面有顯示 http://127.0.0.1:8000 表示已經在本機跑起來一個Application Web Server&lt;/p&gt;
&lt;p&gt;![[看到以下畫面有顯示表示已經在本機跑起來.png]]&lt;/p&gt;
&lt;h3 id="gunicorn"&gt;建立Gunicorn 連接起程式&lt;a class="headerlink" href="#gunicorn" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;接下來建立Gunicorn 連接起程式
執行語法：
&lt;code&gt;sudo vim /etc/systemd/system/gunicorn.socket&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;![[建立Gunicorn連接起程式.png]]&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo vim /etc/systemd/system/gunicorn.service&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;![[建立Gunicorn連接起程式2.png]]&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt;
&lt;span class="n"&gt;Requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sutsagent&lt;/span&gt;
&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sutsagent&lt;/span&gt;
&lt;span class="n"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sutsagent&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailDir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailProject&lt;/span&gt;
&lt;span class="n"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sutsagent&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailDir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailEnv&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt; \
     &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;logfile&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; \
     &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;workers&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; \
     &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="n"&gt;unix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt; \
     &lt;span class="n"&gt;WagtailProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wsgi&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Install&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最後執行一些啟動，重啟與狀態查看&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;
&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;unix&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="n"&gt;localhost&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;restart&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="nginx"&gt;設定Nginx的設定檔&lt;a class="headerlink" href="#nginx" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;設定Nginx，建立一個自定義名稱設定檔，我定義為 gcp.mooo.com&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo vim /etc/nginx/sites-available/gcp.mooo.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Nginx的一些設定，主要設定server_name要對應自己的Domain，與location的路徑&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;server&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mooo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mooo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;favicon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;access_log&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;log_not_found&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sutsagent&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailDir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WagtailProject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="n"&gt;proxy_params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//unix:/run/gunicorn.sock;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最後：將檔案連結到啟動網站的目錄來啟動該檔案
&lt;code&gt;sudo ln -s /etc/nginx/sites-available/pgcp.mooo.com /etc/nginx/sites-enabled&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;執行最後語法：測試nginx與重啟&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;nginx&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;nginx&lt;/span&gt; &lt;span class="n"&gt;restart&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="_2"&gt;後續&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;p&gt;後續開發都是使用VSCode，發現使用Remote SSH連線遠端直接修改設定檔還比較快
另外記錄使用方式： [[使用VSCode遠端SSH開發]]&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@huiqinng/%E7%AD%86%E8%A8%98-%E5%9C%A8gcp%E4%B8%8A%E5%BB%BA%E7%AB%8B%E5%8F%AFremote-dekstop%E7%9A%84ubuntu%E7%92%B0%E5%A2%83-e56fdbd3a4f2"&gt;【筆記】在GCP上建立可Remote dekstop的Ubuntu環境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://infinitewing.github.io/2017/08/13/20170813001/"&gt;在GCP開啟Ubuntu遠端桌面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cloudbooklet.com/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04-in-google-cloud/"&gt;How To Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 18.04 in Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/tsungs-blog/django-%E5%9C%A8ubuntu%E4%B8%AD%E9%81%8B%E7%94%A8nginx-gunicorn-%E6%9E%B6%E8%A8%AD-django-api-server-6d41c165a2c7"&gt;[Django] 在Ubuntu中運用Nginx、Gunicorn 架設 Django &lt;span class="caps"&gt;API&lt;/span&gt; Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="網路概論"></category><category term="GoogleCloudPlatform"></category><category term="WagtailCMS"></category></entry><entry><title>使用VSCode遠端SSH開發</title><link href="https://blog.richardnote.com/2020/08/VisualStudioCode-GCP/" rel="alternate"></link><published>2020-08-25T18:22:00+08:00</published><updated>2020-08-25T18:22:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2020-08-25:/2020/08/VisualStudioCode-GCP/</id><summary type="html">&lt;p&gt;使用VSCode遠端開發，透過Remote-&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/p&gt;</summary><content type="html">
&lt;h2 id="ssh-key"&gt;產生SSH &lt;span class="caps"&gt;KEY&lt;/span&gt;&lt;a class="headerlink" href="#ssh-key" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;開啟 Terminal 執行以下語法，可以看到路徑預設在 &lt;code&gt;/Users/你的名稱/.ssh&lt;/code&gt; 下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;ssh-keygen&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如下圖，要求輸入名稱或是直接按Enter產生預設名稱id_rsa，我輸入jarvis.zheng-GithHub&lt;/p&gt;
&lt;p&gt;![[ssh-key產生.jpg]]&lt;/p&gt;
&lt;p&gt;在Mac 下使用快捷鍵來查看隱藏資料夾： &lt;code&gt;Command + Shift +  .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;公鑰 (jarvis.zheng-GithHub.pub) 以及私鑰 (jarvis.zheng-GithHub)， 公鑰到時候要複製到GCP上，而私鑰則是自己用，雙方才能夠溝通。&lt;/p&gt;
&lt;p&gt;![[產生的公鑰與私鑰.jpg]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;如下圖，是GCP的Compute Engine 上面設定公鑰的地方&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;![[在GCP上面把公鑰複製上去.jpg]]&lt;/p&gt;
&lt;p&gt;如下圖在VSCode安裝外掛套件，Remote Development&lt;/p&gt;
&lt;p&gt;![[VSCode安裝RemoteDevelopment.jpg]]&lt;/p&gt;
&lt;p&gt;安裝完成後，在 VSCode介面的左下角可以看到圖標，按下去顯示清單，選擇Connect to Host，輸入要連線的伺服器，格式 username@server_host&lt;/p&gt;
&lt;p&gt;就是GCP上面的： 使用者名稱@外部IP&lt;/p&gt;
&lt;p&gt;![[在VScode安裝並且連線GCP的外部IP.jpg]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;番外篇：
&lt;span class="caps"&gt;SSH&lt;/span&gt; Key產生的時候權限問題 ，無法儲存檔案問題，&lt;/p&gt;
&lt;p&gt;完美解決： https://stackoverflow.com/questions/51614552/google-cloud-platform-ssh-to-google-cloud-instance-will-have-permission-denied&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.wowfuncode.com/2020/07/14/vscode-using-remote-ssh/"&gt;&lt;span class="caps"&gt;VS&lt;/span&gt; Code 使用 Remote – &lt;span class="caps"&gt;SSH&lt;/span&gt; 開啟遠端 Linux 資料夾&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="VisualStudioCode"></category><category term="GoogleCloudPlatform"></category></entry><entry><title>VS 常用內建快速鍵</title><link href="https://blog.richardnote.com/2016/03/VisualStudio/" rel="alternate"></link><published>2016-03-08T12:43:00+08:00</published><updated>2021-11-18T16:32:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2016-03-08:/2016/03/VisualStudio/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;VS&lt;/span&gt;&amp;nbsp;常用內建快速鍵&lt;/p&gt;</summary><content type="html">
&lt;hr/&gt;
&lt;p&gt;![[Pasted image 20210917172329.png]]&lt;/p&gt;
&lt;h2 id="_1"&gt;環境&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="_2"&gt;環境設定的組合快捷鍵&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;hr/&gt;
&lt;p&gt;程式碼編輯器分頁切換 ：Ctrl+&lt;span class="caps"&gt;TAB&lt;/span&gt; 
存檔：Ctrl + S 
執行(debug)：F5
==執行(non debug)==：&lt;code&gt;Ctrl + F5&lt;/code&gt;
全部儲存：Ctrl + Shift + S 
 單步執行：F11 (F10) 
切換斷點：F9 
==啟用/停用斷點==：&lt;code&gt;Ctrl + F9&lt;/code&gt;
==刪除所有斷點==：&lt;code&gt;Ctrl + Shift + F9&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="_3"&gt;編輯&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="_4"&gt;編輯程式時的組合快捷鍵&lt;a class="headerlink" href="#_4" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;hr/&gt;
&lt;p&gt;==註解選取範圍==：&lt;code&gt;Ctrl+K,C&lt;/code&gt; 
==取消註解選取範圍==：&lt;code&gt;Ctrl+K,U&lt;/code&gt;
 ==自動縮排==：&lt;code&gt;選取範圍後，Alt + F8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;選取文字改小寫：Ctrl + U 
選取文字改大寫：Ctrl + Shift + U 
==呼叫出類別成員==：&lt;code&gt;Ctrl + J&lt;/code&gt;
(編到一半時 tips 突然不見很好用) &lt;/p&gt;
&lt;p&gt;收攏原始碼：Ctrl + M, O 
展開原始碼：Ctrl + M, L 
==刪除目前這行==：&lt;code&gt;Ctrl + Shift + L&lt;/code&gt;
轉至定義： F12 
檔案最前面：Shift + Home 
檔案最後面：Shift + End 
==選到最前面==：Ctrl + Shift + Home 
==選到最後面==：Ctrl + Shift + End 
檢查括號匹配：Ctrl + ] 
跳至行號：Ctrl + G &lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="visualstudiocode"&gt;VisualStudioCode&lt;a class="headerlink" href="#visualstudiocode" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="vscode"&gt;VSCode環境的編輯快捷鍵&lt;a class="headerlink" href="#vscode" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Code Formatting Shortcut:&lt;/p&gt;
&lt;p&gt;以下的設定在 &lt;span class="caps"&gt;VS2019&lt;/span&gt; 的設定是 ： &lt;code&gt;Ctrl + K  + D&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on Windows ： &lt;code&gt;Shift + Alt + F&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on MacOS : &lt;code&gt;Shift + Option + F&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on Ubuntu : &lt;code&gt;Ctrl + Shift + I&lt;/code&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="VisualStudio"></category><category term="微軟筆記"></category></entry></feed>