为什么使用react-admin为API端点获取404?

时间:2018-06-12 09:34:58

标签: reactjs api go cors gin

使用gin语言

创建后端API使用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

2 个答案:

答案 0 :(得分:1)

为跨域请求添加CORS中间件。我更愿意使用postman来检查它是否正常工作。以下是在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的{​​{1}}配置为

cors

有关gin

的结帐CORS middleware的详细信息

答案 1 :(得分:0)

这种方式有效:

mydata[t] = wb.DataReader(t, data_source='yahoo', start='1995-1-1')['Adj Close']

由于ra-data-json-server