![](/img/trans.png)
[英]Error with Blazor WebAssembly Project after upgrade to net5.0
[英]NET5.0 Blazor WASM CORS client exception
我有一個 Blazor WASM 應用程序和一個 Web Api 由 Blzor 通過 HttpClient 調用。 這兩個程序都在同一台機器上運行(並且在生產環境中運行,這對於小型企業應用程序來說應該不會太奇怪。)。
從 Blazor 客戶端調用 Web Api 導致客戶端 CORS 異常
CORS 策略已阻止從來源“https://localhost:5001”訪問“http://localhost:4040/”:請求的資源上不存在“Access-Control-Allow-Origin”header。 如果不透明的響應滿足您的需求,請將請求的模式設置為“no-cors”以獲取禁用 CORS 的資源。
這是這種情況的預期行為。
在我在 PHP 開發的一個以前的 api 項目中,它具有相同的客戶端行為,我可以通過簡單地設置響應 header 例如繞過 CORS 異常
$response = new Response;
$response->setState(false, $route->command);
...
header("Access-Control-Allow-Origin: *");
echo $response;
現在我想在我的 .net 5.0 Web Api 中使用它。我在 inte.net 中找到了不同的文檔來處理這個問題,就像在
https://learn.microsoft.com/de-de/as.net/core/security/cors?view=as.netcore-5.0 https://www.c-sharpcorner.com/article/enabling-cors-in -asp.net-core-api-application/ https://learn.microsoft.com/en-us/do.net/api/microsoft.as.netcore.cors.infrastructure.corspolicybuilder.withorigins?view=as.netcore -5.0
並在我的 api 中實施
public class Startup {
//---------------------------------------------------------------------
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
//---------------------------------------------------------------------
public IConfiguration Configuration { get; }
//---------------------------------------------------------------------
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices
(
IServiceCollection services
)
=> services
.AddCors()
.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "api", Version = "v1"}) )
.AddControllers()
;
//---------------------------------------------------------------------
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure
(
IApplicationBuilder app,
IWebHostEnvironment env
)
=> app.
apply( _ =>
{
if (true) //(env.IsDevelopment())
{
app
.UseDeveloperExceptionPage()
.UseSwagger()
.UseSwaggerUI( c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "api v1") );
}
})
.UseCors( cors =>
cors
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed( _ => true )
.AllowCredentials()
)
.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseEndpoints( e => e.MapControllers() )
;
//---------------------------------------------------------------------
}
甚至嘗試在 ApiController 中設置 Response Header
[Route("/")]
[ApiController]
public sealed class ServertimeController : ControllerBase
{
//[EnableCors("AllowOrigin")]
[HttpGet]
public Servertime Get() {
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT");
return servertime();
}
}
Blazor WASM 客戶端看起來像
private async void onClick()
{
var response = await httpClient.GetFromJsonAsync<Servertime> ("http://localhost:4040");
message = response.servertime;
this.StateHasChanged();
}
但它仍然導致客戶端 CORS 異常。 為了繞過這個進行開發,我使用了瀏覽器擴展“CORS Unblock”,但這不是部署的選項。
避免 Blazor 客戶端異常的正確方法是什么,我錯過了什么?
@Dmitriy Grebennikov 的回答也是有效的,但需要一些改進才能使其更安全。
在Startup.cs
ConfigureServices
,在services.AddControllers();
前添加如下代碼services.AddControllers();
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
builder.WithOrigins("https://localhost:44338")
.AllowAnyMethod()
.AllowAnyHeader());
});
確保您的網址不應以/
結尾。
您可以將許多 url 傳遞給WithOrigins
方法。 最后在Startup.cs
的Configure
方法中,在app.UseAuthorization();
之前添加以下行app.UseAuthorization();
在app.UseRouting();
app.UseCors();
代碼現在應該可以工作了。
只需將此添加到 ConfigureServices 方法:
services.AddCors(options =>
{
options.AddPolicy("DevCorsPolicy", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
這是配置方法:
app.UseCors("DevCorsPolicy");
對於Blazor WASM 中的解決方案,不在服務器端,此代碼片段
Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserRequestMode(
httpRequestMessage,
Microsoft.AspNetCore.Components.WebAssembly.Http.BrowserRequestMode.NoCors
);
將告訴運行本地 PWA 的本地瀏覽器不要隨請求發送 CORS。
代碼示例(帶有調用和使用的命名空間)
HttpRequestMessage httpRequestMessage = new HttpRequestMessage{
RequestUri = new Uri("[Adress]"),
Content = new StringContent(),
Method = HttpMethod.Post };
WebAssemblyHttpRequestMessageExtensions.SetBrowserRequestMode(httpRequestMessage, BrowserRequestMode.NoCors);
HttpResponseMessage response = client.SendAsync(httpRequestMessage).Result;
--> 來自“Dmitry Grebennikov”的版本有效。 在我的版本中,Post 不是異步的,PWA 會拋出錯誤。
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = new HttpMethod("GET"),
RequestUri = new Uri($"{site.BaseUrl}robots.txt")
};
request.Headers.Add("Accept", "text/plain");
request.SetBrowserRequestMode(BrowserRequestMode.NoCors);
var response = await client.SendAsync(request);
var txt = await response.Content.ReadAsStringAsync();
參考
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.