學習ASP.NET Core(11)-解決跨域問題與程式部署

Jscroop發表於2020-06-18

上一篇我們介紹了系統日誌與測試相關的內容並新增了相關的功能;本章我們將介紹跨域與程式部署相關的內容

一、跨域

1、跨域的概念

1、什麼是跨域?

一個請求的URL由協議,域名,埠號組成,以百度的https://www.baidu.com為例,協議為https,域名由子域名www和主域名baidu組成,埠號若為80會自動隱藏(也可以配置為其它埠,通過代理伺服器將80埠請求轉發給實際的埠號)。而當請求的URL的協議,域名,埠號任意一個於當前頁面的URL不同即為跨域

2、什麼是同源策略?

瀏覽器存在一個同源策略,即為了防範跨站指令碼的攻擊,出現跨域請求時瀏覽器會限制自身不能執行其它網站的指令碼(如JavaScript)。所以說當我們把專案部署到Web伺服器後,通過瀏覽器進行請求時就會出現同源策略問題;而像PostMan軟體因其是客戶端形式的,所以不存在此類問題

3、跨域會導致什麼問題?

同源策略會限制以下行為:

  • Cookie、LocalStorage和IndexDb的讀取
  • DOM和JS物件的獲取
  • Ajax請求的傳送

2、常用的解決方法

這裡我們將簡單介紹針對跨域問題常用的幾種解決辦法,並就其中的Cors方法進行配置,若對其它方式感興趣,可參照老張的哲學的文章,⅖ 種方法實現完美跨域

2.1、JsonP

1、原理

上面有提到瀏覽器基於其同源策略會限制部分行為,但對於Script標籤是沒有限制的,而JsonP就是基於這一點,它會在頁面種動態的插入Script標籤,其Src屬性對應的就是api介面的地址,前端會以Get方式將處理函式以回撥的形式傳遞給後端,後端響應後會再以回撥的方式傳遞給前端,最終頁面得以顯示

2、優缺點

JsonP出現時間較早,所以對舊版本瀏覽器支援性較好;但自身只支援Get請求,無法確認請求是否成功

2.2、 CORS

1、原理

CORS的全稱是Corss Origin Resource Sharing,即跨域資源共享,它允許將當前域下的資源被其它域的指令碼請求訪問。其實現原理就是在響應的head中新增Access-Control-Allow-Origin,只要有該欄位就支援跨域請求

2、優缺點

Cors支援所有Http方法,不用考慮介面規則,使用簡單;但是對一些舊版本的瀏覽器支援性欠佳

3、使用

其使用非常簡單,以我們的專案為例,在BlogSystem.Core專案的Startup類的ConfigureServices方法中進行如下配置

同時需要開啟使用中介軟體,如下:

2.3、Nginx

1、原理

跨域問題是指在一個地址中發起另一個地址的請求,而Nginx可以利用其反向代理的功能,接受請求後直接請求該地址,類似開啟了一個新的頁面,所以可以避開跨域的問題

2、優缺點

配置簡單,可以降低開發成本,方便配置負載均衡;靈活性差,每個環境都需要進行不同的配置

二、程式部署

1、部署模式

在.NET Core中,有兩種部署模式,分別為FDD(Framework-dependent)框架依賴釋出模式和SCD(Self-contained)自包含獨立釋出模式

  • FDD:此類部署需要伺服器安裝.NET Core SDK環境,部署的包容量會比較小,但可能因SDK版本存在相容性問題;
  • SCD:此類部署自包含.NET Core SDK的環境,不同.NET Core版本可以共存,其部署包容量會較大,且需要對伺服器進行相關配置

2、常用部署方式

以下內容均參考老張的哲學的文章最全的部署方案 & 最豐富的錯誤分析,有興趣的朋友可以參考原文

2.1、Windows平臺

  • 直接執行:釋出目標選擇windows時會在資料夾中生成一個exe檔案,我們可以直接執行exe檔案或使用CLI命令呼叫dll執行;這種方式雖然方便,卻存在一些弊端,比如說部署多個的情況下會存在很多控制檯視窗,如誤操作會導致視窗關閉等;
  • 部署服務:除了上述直接執行的方式外,我們還可以將程式釋出為服務,釋出後我們可以像控制系統服務一樣控制程式的啟動和關閉

需要注意的是上述兩類方法都需要藉助IIS或者是代理伺服器進行服務的轉發,否則只能在本地進行訪問;

2.2、Linux平臺

Linux平臺常用的部署方式即為程式+代理伺服器,但是當我們配置完成後執行程式時,該執行命令會一直佔用操作視窗,所以我們需要使用“守護程式”來解決這個問題,簡單來說就是將程式放到後臺執行,不影響我們進行其他操作

綜上,部署模式、部署方式及部署平臺有多種組合方式,接下來我們挑選下述3種方法進行演示:

方案 依賴執行時/宿主機 依賴代理伺服器 其它配置
Windows程式(SCD)+Nginx
Windows服務(FDD)+IIS 設定為服務
Linux程式(FDD)+Nginx 守護程式

3、程式釋出

1、這裡我們右擊BlogSystem.Core專案,選擇釋出,選擇資料夾後,點選高階

2、為了演示後面的釋出例項,這裡我們分別選擇3種組合模式,①獨立+win-x64;②框架依賴+win-x64;③框架依賴+linux-x64

3、將釋出例項拷貝到單獨的資料夾種,這裡我們使用SCD-Window驗證下程式能否直接執行,執行BlogSystem.Core.exe,報錯:

原來還是老問題,BLL沒有新增到釋出檔案中,我們到專案的bin資料夾下將BLL和DAL的dll檔案分別拷貝至3個資料夾,再次執行,出現404錯誤,經過確認發現,首頁對應的是Swagger文件頁面,而在配置中介軟體時我們有新增開發環境才配置swagger的邏輯,所以這裡我們可以根據個人需求決定是否新增。

這裡我為了方便確認釋出是否成功,所以將其從判斷邏輯中取出了。重新生成釋出檔案,拷貝BLL和DAL的dll檔案,再次執行,還是報錯。原來時Swagger的XML檔案缺失,從bin資料夾下拷貝新增至釋出檔案,執行後成功顯示頁面

4、有的朋友會說了,每次都要拷貝這兩個dll和這兩個xml檔案,太麻煩了。其實也是有對應的解決辦法的,我們可以使用dotnet的CLI命令進行釋出,選擇引用的釋出資料夾為bin資料夾,拷貝至釋出資料夾即可,有興趣的朋友可以自行研究

三、伺服器釋出

這裡我用的是阿里雲伺服器,Window系統版本是Window Server2012 R2,Linux系統版本是CentOS 8.0;在操作前記得確認拷貝的釋出檔案能否在本地正常執行

1、Windows程式(SCD)+Nginx

1、解壓後雙擊exe檔案網站可以正常執行,如下:

2、這個時候我們發現了一個問題,伺服器上沒有資料庫,所以無法確認功能是否正常,這裡我們先下載安裝一個Microsoft SQL Server 2012 Express資料庫(建專案時沒有考慮到釋出後測試的問題,實際上像SQLite資料庫是非常符合這類場景的)

安裝完成後我們新建一個BlogSystem的資料庫,通過Sql檔案的形式將資料庫結構和資料匯入至伺服器資料庫,這時候又發現一個問題,由於我們連線資料庫的邏輯放置在model層的BlogSystemContext資料夾下,所以需要將連線中的DataSource更改為Express資料庫,重新發布後覆蓋舊的釋出檔案(系統設計有缺陷,可以將EF上下文檔案放在應用程式層或單獨一層),再次執行,成功執行查詢,如下:

3、這個時候本地已經可以進行正常的訪問了,但是外部網路是無法訪問呼叫介面的,這裡我們藉助Nginx進行服務的轉發。下載Nginx後解壓對conf資料夾下的nginx.conf檔案進行如下配置:

4、在nginx.exe檔案所在目錄的檔案路徑輸入cmd,鍵入nginx啟動服務訪問8081埠,成功顯示頁面(確保core程式正常執行)如下:

5、這個時候我們使用其它電腦訪問介面,發現還是無法訪問,經過查詢是阿里雲伺服器進行了相關的限制,在阿里雲控制檯配置安全組規則後即可正常訪問,如下:

6、配置完成後執行,成功訪問該網站且功能正常。這類方法不需要藉助Core的執行時環境,可以說十分便捷

2、Windows服務(FDD)+IIS

1、首先我們將FDD釋出檔案壓縮後拷貝至Window Server主機,因FDD的部署方法需要藉助.NET Core執行時環境,所以這裡我們首先到官網https://dotnet.microsoft.com/download/dotnet-core/current/runtime下載安裝.NET Core執行時,這裡我們選擇的是右邊這個,安裝完需要重新啟動

2、上一個方法中桌面顯示控制檯視窗顯然不是一個較佳的方案,所以這裡我們將其註冊為服務。官方提供了ASP.NET Core服務託管的方法,但使用較為複雜,這裡我們藉助一個名為nssm的工具來達到同樣的目的。我們下載nssm後,在其exe路徑執行cmd命令,執行nssm install,在彈出的視窗中進行如下配置:

3、我們在系統服務中開啟BlogSytem.Core_Server,在控制面版中選擇安裝IIS服務,併發布對應的專案,安裝完成後,新增部署為8082埠,將應用程式池修改為無託管,如下:

4、執行網站,成功顯示頁面,但是進行功能試用時發現報錯;經過確認是由於IIS應用程式池的使用者驗證模式和sqlserver的驗證模式不同,解決辦法有三種①修改應用程式池高階設定中的程式模型中的標識②將連線資料庫字串中的Integrated Security=True去除,並新增資料庫連線對應的賬號密碼③在資料庫的“安全性”>“登入名”裡面,新增對應IIS程式池的名稱,並在這個使用者的“伺服器角色”和“使用者對映”中給他對應的許可權

後續嘗試方案一失敗,嘗試方案二成功,方案三由於要安裝SSMS所以沒有嘗試,有遇到相同問題的朋友可以自己試下

3、Linux程式(FDD)+Nginx

1、首先我們使用MobaXterm工具登入至Linux主機(選擇此工具是由於其)同時支援檔案傳送和命令列操作),這裡使用的Linux版本是CentOS 8.0;藉助MobaXterm工具在home資料夾下建立WebSite資料夾,並在其內部建立BlogSystem資料夾,將我們準備好的FDD部署方式的釋出檔案上傳至此資料夾後,使用命令sudo dnf install dotnet-sdk-3.1安裝.net core sdk,如下圖

2、輸入cd /home/WebSite/BlogSystem切換至專案資料夾後,使用dotnet BlogSystem.Core.dll執行程式,成功執行,但是由於我們沒有資料庫,且未配置代理伺服器,所以無法驗證服務是否正常執行;所以這裡我們先參照微軟doc快速入門:在 Red Hat 上安裝 SQL Server 並建立資料庫安裝Sql Server資料庫(阿里雲預設安裝了python3作為直譯器所以無需重複安裝),安裝完成後我們開放在阿里雲例項中開放1433埠,使用視覺化工具匯入表結構和資料

3、完成上述操作後我們需要配置守護程式,將程式放在後臺執行。首先我們在/etc/systemd/system下新建守護程式檔案,檔名以.service結尾,這裡我們新建名為BlogSystem.service檔案,使用MobaXterm自帶的編輯器開啟檔案後進行如下配置,注意後面的中文備註需要去除否則會報錯

[Unit]
Description=BlogSystem    #服務描述,隨便填就好

[Service]
WorkingDirectory=/home/WebSite/BlogSystem/   #工作目錄,填你應用的絕對路徑
ExecStart=/usr/bin/dotnet /home/WebSite/BlogSystem/BlogSystem.Core.dll    #啟動:前半截是你dotnet的位置(一般都在這個位置),後半部分是你程式入口的dll,中間用空格隔開
Restart=always  
RestartSec=25 #如果服務出現問題會在25秒後重啟,數值可自己設定
SyslogIdentifier=BlogSystem  #設定日誌標識,此行可以沒有
User=root   #配置服務使用者,越高越好
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target

我們使用cd /etc/systemd/system/切換至BlogSystem.service對應的目錄,使用systemctl enable BlogSystem.service設定為開機執行後,再使用systemctl start BlogSystem.service啟動服務,另外可以使用systemctl status BlogSystem確認服務狀態

4、接下來我們安裝代理Nginx代理預設的5000埠,使用sudo yum install nginx安裝nginx後,我們到\etc\nginx資料夾下開啟nginx.conf檔案進行如下配置:

配置完成我們進入\etc\nginx資料夾下,使用systemctl enable nginx將nginx設定為開機啟動,並使用systemctl start nginx啟用服務,同樣可以使用systemctl status nginx確認其狀態。確認無誤後在阿里雲中開放8081埠,外網可正常訪問,但功能試用時報錯,原來是資料庫連線錯誤,重新設定後即可正常訪問

本章完~


本人知識點有限,若文中有錯誤的地方請及時指正,方便大家更好的學習和交流。

本文部分內容參考了網路上的視訊內容和文章,僅為學習和交流,地址如下:

老張的哲學,系列一、ASP.NET Core 學習視訊教程

solenovex,ASP.NET Core 3.x 入門視訊

宣告

相關文章