在.NET?WebService中跨域CORS問題的解決方案
引言
在現代的Web應用程序開發(fā)中,跨域資源共享(Cross-Origin Resource Sharing, CORS)問題是開發(fā)者經常遇到的一個挑戰(zhàn)。特別是當前端和后端服務部署在不同的域名或端口時,CORS問題就會顯得尤為突出。在這篇博客中,我們將深入探討如何在 .NET WebService 中解決CORS問題,幫助開發(fā)者順利實現跨域請求。
一、CORS問題描述
在Web應用中,瀏覽器安全機制通常會阻止來自不同域的請求,這被稱為“同源策略”。同源策略允許同一來源(協(xié)議、主機和端口相同)的資源相互訪問,但會阻止不同來源的資源訪問。這種機制雖然提高了安全性,但在實際開發(fā)中,前端和后端通常會部署在不同的服務器上,這就引發(fā)了CORS問題。
舉個例子,當你試圖從 http://frontend.com 發(fā)送一個請求到 http://api.backend.com 時,瀏覽器會攔截這個請求并拋出一個CORS錯誤:
Access to XMLHttpRequest at 'http://api.backend.com/resource' from origin 'http://frontend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
對于 .NET WebService ,如果前端應用嘗試從另一個域名訪問服務,而服務端沒有適當的CORS策略,那么瀏覽器會阻止這些請求并顯示該跨域錯誤。
二、CORS問題代碼示例
為了更好地理解CORS問題及其解決方案,讓我們先創(chuàng)建一個簡單的前后端交互的.NET WebService示例。
1. 后端WebService接口代碼
首先,創(chuàng)建一個新的 .NET Framework 項目。你可以使用 Visual Studio 或者命令行工具(如 dotnet CLI )來創(chuàng)建項目。在項目中,我們定義一個 .asmx 文件,并在 .asmx.cs 文件里創(chuàng)建一個接口。


接口代碼如下:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.Services;
namespace TestProject
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Test : WebService
{
[WebMethod]
public void GetJsonData()
{
string json = "{\"MapPoints\":[{\"Coordinates\":[\"118.87220827635\",\"34.885061248714\"],\"Speed\":\"45.7\",\"Time\":\"2024-05-13T13:02:09\"}]}";
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(json);
}
}
}
這個控制器有一個GET方法,當請求 http://localhost:80/Test.asmx/GetJsonData 時,它會返回一個串JSON數據。
這里我們可以用 Postman 測試代碼,正確返回結果,則驗證后端接口代碼沒有問題。

2. 前端接口請求代碼
這里我使用的前端訪問接口的JavaScript代碼是基于 axios 實現的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS Test</title>
</head>
<body>
<h1>CORS Test</h1>
<button id="fetchDataButton">Fetch Data</button>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
document.getElementById('fetchDataButton').addEventListener('click', function () {
getCarLocation();
});
function getCarLocation() {
axios.get('http://localhost:80/Test.asmx/GetJsonData')
.then(function (response) {
console.log('Success:', response.data);
})
.catch(function (error) {
console.error('Error:', error);
});
}
</script>
</body>
</html>
頁面效果圖如下:

當點擊 Fetch Data 按鈕時,頁面會訪問 http://localhost:80/Test.asmx/GetJsonData 接口,并輸出返回值到F12控制臺日志里。
此時,如果我們不配置CORS,那么請求會被攔截,并報錯:
Access to XMLHttpRequest at 'http://localhost:80/Test.asmx/GetJsonData' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
三、CORS配置詳細步驟
為了讓我們的 WebService 支持跨域請求,我們需要在項目中配置CORS。在 .NET Framework 中,我們可以通過如下步驟來配置CORS。
1. 配置Global.asax全局請求頭參數
創(chuàng)建或打開項目的 Global.asax 文件,找到或添加 Application_BeginRequest() 方法,添加響應頭參數,其中 <"Access-Control-Allow-Origin", "*"> 這個響應頭是最重要的。
namespace TestProject
{
public class Global : System.Web.HttpApplication
{
protected void Application_BeginRequest()
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, X-Requested-With");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "86400");
HttpContext.Current.Response.StatusCode = 204;
HttpContext.Current.Response.End();
}
}
}
}
要非常注意的是,每個請求頭參數只能添加一次,如果重復添加,依然會訪問報錯,可以排查一下 web.config 文件或者專門的路由模塊有沒有已經添加,或者再每次添加之前判斷當前請求頭是否已經存在,如果存在刪除在添加。
2. 創(chuàng)建自定義HTTP模塊并注冊
在 .NET Framework 中,通過自定義 HTTP 模塊修改 HTTP 響應頭,可以協(xié)助處理跨域問題。
我們右鍵解決方案,新建項目,創(chuàng)建 ??CustomHttpModules?? 模塊。


模塊內創(chuàng)建 HeaderFilterHttpModule.cs 文件。

代碼如下 :
using System;
using System.Web;
namespace CustomHttpModules
{
public class HeaderFilterHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
public void Dispose()
{ }
void OnPreSendRequestHeaders(object sender, EventArgs e)
{
try
{
HttpApplication app = sender as HttpApplication;
if (app != null && app.Context != null && app.Context.Response != null)
{
var headers = app.Context.Response.Headers;
if (headers != null)
{
headers.Remove("Server");
headers.Remove("X-AspNet-Version");
headers.Remove("X-AspNetMvc-Version");
headers.Remove("X-Frame-Options");
headers.Remove("X-Powered-By");
// 添加CORS相關的頭信息
headers.Add("Access-Control-Allow-Origin", "*");
headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");
}
}
}
catch (Exception ex)
{
// 記錄異常
}
}
}
}
創(chuàng)建完成后,我們到主項目注冊這個自定義的 HTTP 模塊。
打開 web.config 文件,找到 <configuration> 下的 <system.webServer> 標簽,引入我們剛剛創(chuàng)建好的 HeaderFilterHttpModule 模塊。
<configuration>
<system.webServer>
<modules>
<add name="HeaderFilterHttpModule" type="CustomHttpModules.HeaderFilterHttpModule" />
</modules>
</system.webServer>
</configuration>
3. 測試增加CORS配置后的代碼
添加上述有關CORS的配置后,我們重新啟動 .NET Framework 項目,通過測試頁面點擊 Fetch Data 按鈕,給 http://localhost:80/Test.asmx/GetJsonData 接口發(fā)送請求。
可以看到我們得到了正確的返回值。
{
"MapPoints": [
{
"Coordinates": [
"118.87220827635",
"34.885061248714"
],
"Speed": "45.7",
"Time": "2024-05-13T13:02:09"
}
]
}
.NET WebService 跨域CORS問題完美解決。
四、CORS問題解決總結
通過配置 global.asax 全局文件,創(chuàng)建和注冊自定義 HTTP 模塊,我們成功地解決了 .NET WebService 中的 CORS 問題。這種方法的關鍵在于攔截和修改 HTTP 響應頭,添加必要的 CORS 頭信息??偨Y如下:
- 修改Global.asax文件:修改
Application_BeginRequest方法,修改全局請求頭參數。 - 創(chuàng)建自定義 HTTP 模塊:實現
IHttpModule接口,并在PreSendRequestHeaders事件中添加或移除 HTTP 頭信息。 - 注冊 HTTP 模塊:在
Web.config文件中注冊自定義的 HTTP 模塊。 - 測試能否跨域:通過前端發(fā)送跨域請求來驗證 CORS 配置是否正確。
通過這些步驟,開發(fā)者可以有效地解決跨域資源共享問題,確保前后端服務的順暢通信。在實際開發(fā)中,根據具體項目的需求,CORS 配置可能會有所不同,但核心思想和步驟是類似的。希望這篇博客能為你解決 CORS 問題提供有價值的幫助。
以上就是在.NET WebService中解決CORS問題的解決方案的詳細內容,更多關于 .NET WebService CORS問題的資料請關注腳本之家其它相關文章!
相關文章
使用linq to xml修改app.config示例(linq讀取xml)
這篇文章主要介紹了使用linq to xml修改app.config示例,需要的朋友可以參考下2014-02-02

