Reputation: 653
gin
with go
languagetype 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
with react-admin
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;
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>
);
When access http://localhost:3000
from chrome browser, got Failed to fetch
message. From the console I saw:
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.
I have tried to add Access-Control-Allow-Origin
in the go API program, but the same result. From the gin
output I got:
[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
Added cors
package then change source as:
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()
}
Got same error again:
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.
This time, the output of gin
was:
[GIN] 2018/06/13 - 11:01:59 | 403 | 7.873µs | ::1 | OPTIONS /posts?_end=10&_order=DESC&_sort=id&_start=0
Upvotes: 1
Views: 2699
Reputation: 653
This way works:
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)
}
}
Due to ra-data-json-server.
Upvotes: 0
Reputation: 12675
Add CORS
middleware for cross origin domain requests. I would prefer to hit the api using postman
to check if it is working fine. Below is the way to implement CORS
middleware for 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()
}
Edited: For allowing all origins use Default
config for 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()
}
For more information checkout CORS middleware for gin
Upvotes: 1