为啥使用 react-admin 获得 404 的 API 端点?

Posted

技术标签:

【中文标题】为啥使用 react-admin 获得 404 的 API 端点?【英文标题】:Why got 404 for API endpoint with react-admin?为什么使用 react-admin 获得 404 的 API 端点? 【发布时间】:2018-11-21 15:44:18 【问题描述】:

创建的后端 API 使用 gingo 语言

type Post struct 
    ID uint `json:"id"`
    Title string `json:"title"`
    Body string `json:"body"`


func main() 
    // ...
    r := gin.Default()
    r.GET("/posts", GetPosts)
    r.GET("/posts/:id", GetPost)
    r.POST("/posts", CreatePost)
    r.PUT("/posts/:id", UpdatePost)
    r.DELETE("/posts/:id", DeletePost)

    r.Run(":8080")


func GetPosts(c *gin.Context) 
    var posts []Post
    c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
    if err := db.Find(&posts).Error; err != nil 
            c.AbortWithStatus(404)
            fmt.Println(err)
     else 
            c.JSON(200, post)
    


// ...

创建的前端使用 reactreact-admin

src/App.js

import React from 'react';
import  Admin, Resource  from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
import  PostList  from './posts';

const dataProvider = jsonServerProvider('http://localhost:8080');

const App = () => (
        <Admin dataProvider=dataProvider>
    <Resource name="posts" list=PostList />
        </Admin>
);

export default App;

src/posts.js

import React from 'react';
import  List, Datagrid, TextField  from 'react-admin';

export const PostList = (props) => (
    <List ...props>
        <Datagrid>
            <TextField source="id" />
            <TextField source="title" />
            <TextField source="body" />
        </Datagrid>
    </List>
);

当从 chrome 浏览器访问 http://localhost:3000 时,收到 Failed to fetch 消息。从我看到的控制台:

Failed to load http://localhost:8080/posts?_end=10&_order=DESC&_sort=id&_start=0: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 404. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

我尝试在 go API 程序中添加Access-Control-Allow-Origin,但结果相同。从gin 输出我得到:

[GIN] 2018/06/12 - 18:14:50 | 404 |       1.813µs |       127.0.0.1 | OPTIONS  /posts?_end=10&_order=DESC&_sort=id&_start=0

添加

添加 cors 包然后将源更改为:

package main

import (
        "fmt"

        "github.com/gin-contrib/cors"
        "github.com/gin-gonic/gin"
        // ...
)

// ...

func main() 
    r := gin.Default()

    r.Use(cors.New(cors.Config
            AllowOrigins: []string"http://localhost:8080",
    ))

    r.GET("/posts", GetPosts)
    r.GET("/posts/:id", GetPost)
    r.POST("/posts", CreatePost)
    r.PUT("/posts/:id", UpdatePost)
    r.DELETE("/posts/:id", DeletePost)

    r.Run()

又遇到同样的错误:

Failed to load http://localhost:8080/posts?_end=10&_order=DESC&_sort=id&_start=0: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

这一次,gin 的输出是:

[GIN] 2018/06/13 - 11:01:59 | 403 |       7.873µs |             ::1 | OPTIONS  /posts?_end=10&_order=DESC&_sort=id&_start=0

【问题讨论】:

尝试为golang代码添加gin的CORS中间件,允许跨域请求访问 @Himanshu 我添加了一个中间件但得到了相同的结果。 【参考方案1】:

为跨域请求添加CORS 中间件。我宁愿使用postman 访问 api 来检查它是否工作正常。下面是在go中为gin实现CORS中间件的方法:-

package main

import (
    "time"

    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
)

func main() 
    router := gin.Default()
    // CORS for http://localhost:8080 and https://github.com origins, allowing:
    // - PUT and PATCH methods
    // - Origin header
    // - Credentials share
    // - Preflight requests cached for 12 hours
    router.Use(cors.New(cors.Config
        AllowOrigins:     []string"http://localhost:8080, https://localhost:8080",
        AllowMethods:     []string"GET", "POST", "HEAD", "PUT", "PATCH",
        AllowHeaders:     []string"Origin",
        ExposeHeaders:    []string"Content-Length",
        AllowCredentials: true,
        MaxAge: 12 * time.Hour,
    ))
    router.Run()

已编辑:为了允许所有来源使用 Default 配置 cors as

func main() 
    router := gin.Default()
    // same as
    // config := cors.DefaultConfig()
    // config.AllowAllOrigins = true
    // router.Use(cors.New(config))
    router.Use(cors.Default())
    router.Run()

欲了解更多信息,请查看CORS middleware 获取杜松子酒

【讨论】:

谢谢。我已经添加了那个包。但又是同样的结果。我已将来源添加到问题中。 你需要设置 AllowOrigins("localhost:8080") & AllowMethods & AllowHeaders("Origin") 如果设置localhost:8080会在启动服务器时导致panic: bad origin: origins must either be '*' or include http:// or https://错误。 @vv 我已经编辑了答案以允许您可以使用Default 配置的所有来源。请检查编辑后的答案 @Himanshu 谢谢。这次得到了Warning: Missing translation for key: "The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?",我也加了X-Total-Count,但没有修复。【参考方案2】:

这种方法有效:

func main() 
        // ...
        r := gin.Default()
        r.Use(cors.New(cors.Config
                AllowOrigins:  []string"http://localhost:3000",
                AllowMethods:  []string"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD",
                AllowHeaders:  []string"Origin", "Content-Length", "Content-Type",
                ExposeHeaders: []string"X-Total-Count",
        ))
        r.GET("/posts", GetPosts)
        // ...
        r.Run()


func GetPosts(c *gin.Context) 
        var posts []Post
        if err := db.Find(&posts).Error; err != nil 
                c.AbortWithStatus(404)
                fmt.Println(err)
         else 
                c.Header("X-Total-Count", "25")
                c.JSON(200, posts)
        

由于ra-data-json-server。

【讨论】:

以上是关于为啥使用 react-admin 获得 404 的 API 端点?的主要内容,如果未能解决你的问题,请参考以下文章

在 react-admin 中获得对 redux 存储的访问权限

react-admin 编辑等待响应

在其他机器上得到 404,为啥?

为啥我不断收到 Socket.io 轮询请求的 404 错误?

仪表板上的 React-admin 组件?

为啥在asp.net中使用自定义404页面时不存在的页面返回302状态