Почему 404 для конечной точки API с реакции-администратора? - PullRequest
0 голосов
/ 12 июня 2018

Создано использование 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>
);

При доступе http://localhost:3000 из браузера Chrome получено сообщение 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.

Я попытался добавить Access-Control-Allow-Origin в программу go API, но результат тот же.Из вывода 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 голосов
/ 15 июня 2018

Этот способ работает:

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 .

0 голосов
/ 12 июня 2018

Добавить CORS промежуточное программное обеспечение для запросов к домену с несколькими источниками.Я бы предпочел поразить API, используя postman, чтобы проверить, работает ли он нормально.Ниже описан способ реализации CORS промежуточного программного обеспечения для gin in go: -

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 config для cors как

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 для джина

...