为啥使用 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 使用 gin
和 go
语言
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)
// ...
创建的前端使用 react
和 react-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 存储的访问权限