设置了 CORS 从后端最小 API 获取数据时出现的问题

问题描述 投票:0回答:1

正如标题所示,我使用 CORS 在 .NET 8 中设置了一个最小的 WEB API,并且路由似乎在后端运行良好,甚至使用 VSCode 中的 REST 客户端扩展测试了 CRUD 操作。

当我尝试从其中一条路线获取数据并将数据记录在控制台上时,我收到此错误:

从源“http://localhost:3000”获取“http://localhost:5050/words”的访问已被 CORS 策略阻止:请求中不存在“Access-Control-Allow-Origin”标头资源。

下面是从路由获取的 React 组件的代码:

import { useEffect } from "react"

const NewWord = () => {

    const submitHandler = async() => {
        try {
            const response = await fetch("http://localhost:5050/words")
            const data = await response.json()
            console.log(data)
        } catch (error) {
            console.error(error)
        }
    }

  return (
    <>
        <h1 className="text-center text-bold text-white">New Word</h1>
        {/* Major container */}
        <div className="">
            {/* Container */}
            <div className="border border-solid p-4 my-4 rounded-xl bg-green-300">

                {/* Word */}
                <div className=" p-2">
                    <input type="text" name="" id="" 
                    placeholder="Word" 
                    className="w-full"/>
                </div>

                {/* Definition */}
                <div className="p-2">
                    <input type="text" 
                    name="" id="" 
                    placeholder="Type your definition here..."
                    className="w-full" />
                </div>

                {/* Example */}
                <div className="p-2">
                    <input type="text" 
                    name="" id="" 
                    placeholder="Example sentence..." 
                    className="w-full"/>
                </div>

                {/* Tags */}
                <div className="p-2">
                    <input type="text" 
                    placeholder="Type a list of comma-separated tags..."
                    className="w-full" />
                </div>

                {/* Language */}
                <div className="p-2">
                    <select name="" id="">
                        <option value="english">English</option>
                        <option value="hausa">Hausa</option>
                        <option value="french">French</option>
                        <option value="arabic">Arabic</option>
                        <option value="wolof">Wolof</option>
                        <option value="zulu">Zulu</option>
                        <option value="swahili">Swahili</option>
                        <option value="igbo">Igbo</option>
                        <option value="xhosa">Xhosa</option>
                    </select>
                </div>

                <div className="mt-2 flex justify-center">
                    <button 
                    className="border-4 rounded-xl p-2 w-full font-bold"
                    onClick={submitHandler}>
                        Submit
                    </button>
                </div>
            </div>


        </div>


    </>
    
  )
}

export default NewWord

和最小的 API:

using AUB_backend;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// DbContext configuration
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));


// CORS configuration
builder.Services.AddCors(options => {
    options.AddPolicy("AllowSpecificOrigin", builder =>
    {
        builder.WithOrigins("http://localhost:3000")
            .AllowAnyMethod()
            .AllowAnyHeader();
    });
});

var app = builder.Build();

// enable CORS
app.UseCors("AllowSpecificOrigin");
app.UseRouting();

// default page
app.MapGet("/", () => "API Default Page");


// CRUD actions

// CREATE a new word
app.MapPost("/words", async(AppDbContext DbContext, Word newWord) => {
    DbContext.Words.Add(newWord); // add new word to db
    await DbContext.SaveChangesAsync(); // save changes to db asynchronously
    return Results.Created($"/words/{newWord.Id}", newWord);
});

// READ all words
app.MapGet("/words", async(AppDbContext DbContext) => {
    var words = await DbContext.Words.ToListAsync(); // fetch words from db
    return Results.Ok(words);
});

// READ an existing word by Id
app.MapGet("/words/{id}", async(AppDbContext DbContext, int id) => {
    var word = await DbContext.Words.FindAsync(id); // fetch word from db using Id

    if (word is not null)
    {
        return Results.Ok(word);
    }
    else
    {
        return Results.NotFound();
    }
});

// UPDATE a word
app.MapPut("/words/{id}", async(AppDbContext DbContext, int id, Word updatedWord) =>
{
    var word = await DbContext.Words.FindAsync(id);
    if (word is null)
    {
        return Results.NotFound();
    }

    // update word properties
    word.Term = updatedWord.Term;
    word.Definition = updatedWord.Definition;
    word.Example = updatedWord.Example;
    word.Tags = updatedWord.Tags;
    word.Language = updatedWord.Language;

    await DbContext.SaveChangesAsync(); // save changes to db
    return Results.Ok(word);
});

// DELETE an existing word
app.MapDelete("words/{id}", async(AppDbContext DbContext, int id) => {
    var word = await DbContext.Words.FindAsync(id); // find word by Id
    if (word is null)
    {
        return Results.Ok(word);
    }

    DbContext.Words.Remove(word); // remove word from db
    await DbContext.SaveChangesAsync(); // save changed
    return Results.NoContent(); // return a 204 response (No Content)

});

app.Run();

c# reactjs cors .net-8.0 minimal-apis
1个回答
1
投票

来自 CORS 以及命名策略和中间件

UseCors
的呼叫必须在
UseRouting
之后进行。

您的中间件管道(结构)应如下所示:

var app = builder.Build();

app.UseRouting();

// enable CORS
app.UseCors("AllowSpecificOrigin");

...

此外,我建议将“http://localhost:3000”放入 appsettings.{Environment}.json 中,并从应用程序设置 (

builder.Configuration
) 中获取值,而不是在代码中进行硬编码(如果您是)计划在不同的环境中托管您的应用程序:暂存和生产。因此,允许的来源(值)是根据其托管环境分配的。参考:访问Program.cs中的配置

© www.soinside.com 2019 - 2024. All rights reserved.