【问题标题】:Reactjs to Webapi on ASP.net Core 2.2 fails with error 415 in app but not in PostmanASP.net Core 2.2 上的 Reactjs 到 Webapi 失败,应用程序中出现错误 415,但 Postman 中没有
【发布时间】:2020-01-12 15:42:08
【问题描述】:

它可以执行 GET OK,但无法执行 POST。我已经尝试了各种 Header 组合。它到本地主机。

这是我的 Reactjs 应用调用

export function saveStaff(data) {
       return fetch(baseUrl, {
    mode: "no-cors",
    method: "POST", 
    headers: {
      Host: "localhost:44370",
      Allow: "GET, POST",
      Accept: "application/json, text/plain",
      "Content-Type": "application/json"
    },
    body: { Name: "tuesday", Department: "tuesday", visitorcount: 0 } // data // JSON.stringify(data)
  })
    .then(handleResponse)
    .catch(handleError);
}

这是来自 Postman 的标题!

POST /api/StaffNamesAPI HTTP/1.1
Host: localhost:44370
Allow: GET, POST
Content-Type: application/json
Accept: application/json, text/plain
User-Agent: PostmanRuntime/7.16.3
Cache-Control: no-cache
Postman-Token: a5b282c7-24e7-46a6-ba22-4f74a31fa9bd,2232ec6c-b3e9-4e29-88e3-abf63675486c
Host: localhost:44370
Accept-Encoding: gzip, deflate
Content-Length: 122
Connection: keep-alive
cache-control: no-cache

 {"Name": "Wednesday TestWithPostman",
    "Department": "Groan",
    "visitorcount": 0 }

这里是 API 控制器

    [HttpPost]
    [Consumes("application/json")] //https://github.com/aspnet/AspNetCore/issues/4396
    public async Task<ActionResult<StaffNames>> PostStaffNames(StaffNames staffNames)
    {
        _context.StaffNames.Add(staffNames);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetStaffNames", new { id = staffNames.Id }, staffNames);
    }

现阶段我的课很简单

public class StaffNames
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
    public int VisitorCount { get; set; }

}

在我的 startup.cs 中,我设置了 CORS

  //https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2#ecors
        services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
                builder =>
                {
                    builder.WithOrigins("http://localhost:3000/",
                        "http://www.contoso.com")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
        });

这是我的 useCors

 app.UseCors(MyAllowSpecificOrigins);
        //https://stackoverflow.com/questions/52896068/reactasp-net-core-no-access-control-allow-origin-header-is-present-on-the-r
        app.UseCors(builder => builder
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());

感谢您的帮助,我已经考虑了好几个小时了!

【问题讨论】:

  • 嗨大卫,没有引号我收到一个错误第 40 行:解析错误:意外的令牌,预期的“,”
  • 我猜原因是将已发布的 JSON 反序列化为 StaffNames 数据类型的问题。很高兴看到StaffNames 类定义更加确定...
  • @netchicken 很高兴您使用我在回答中建议的解决方案解决了问题。您看到了吗?如果您没有问题,您可以接受答案吗?

标签: reactjs asp.net-core fetch asp.net-core-webapi


【解决方案1】:

如果您有两个项目,则需要将模式设置为cors。我遇到了与CORS相同的问题。最后,我通过删除原始网址中的/ 来克服它

services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
            builder =>
            {
                //Do not use `http://localhost:3000/`
                builder.WithOrigins("http://localhost:3000",
                    "http://www.contoso.com")
                    .AllowAnyHeader()
                    .AllowAnyMethod();
            });
    });

Configure method:
app.UseCors(MyAllowSpecificOrigins);

反应:

return fetch(baseUrl, {
        mode: "cors",
        method: "POST",
        headers: {
            Host: "localhost:44370",
            Allow: "GET, POST",
            Accept: "application/json, text/plain",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ Name: "tuesday", Department: "tuesday", visitorcount: 0 })
    })

【讨论】:

    【解决方案2】:

    由于某种原因,使用no-cors 模式会阻止将Content-Type 标头值设置为application/json,并且默认设置为test/plain,这会导致问题。经过一些研究,我发现cors 模式非常适合您的情况,因此首先考虑更多地了解所有这些模式并选择最适合您的模式。

    其次,您需要在操作参数中添加[FromBody] 属性,以允许模型绑定器在服务器端解析json 正文。在客户端,您需要在发送对象之前将其序列化为 json,因为fetch 不会为您执行此操作。最小的工作代码如下所示

    控制器

    [HttpPost]
    [Consumes("application/json")]
    public IActionResult PostStaffNames([FromBody]StaffNames staffNames)
    

    反应

    export function saveStaff(data) {
        return fetch(baseUrl, {
            mode: "cors",
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
        })
        .then(handleResponse)
        .catch(handleError);
    }
    

    【讨论】:

    • 嗨 Alexander,谢谢你的想法,cors,请给我错误 Access to fetch at 'localhost:44370/api/StaffNamesAPI' from origin 'localhost:3000' has been blocked by CORS policy: I include my class ,以及我的问题中 Startup.cs 文件中的 Cors 设置。
    • @netchicken 您可能在Startup.Configure 方法中缺少UseCors 调用
    • 嗨,Alexander,我正在使用它 :-) 我已将 startup.cs 中的代码添加到我的原始帖子中。我可以从我的网站调用 GET,它只是不起作用的 POST。
    • @netchicken 删除尾部斜杠。它应该是 http://localhost:3000 而不是 http://localhost:3000/
    • 嘎啦!!!我讨厌训练斜线 :-) 非常感谢你把我从这样一个恼人的错误中解救出来 :-)
    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 2020-05-25
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多