質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

5536閲覧

axios.post のリクエストが404 を解決したいです

jpskgc

総合スコア19

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2019/07/10 17:22

編集2019/07/10 17:37

前提・実現したいこと

ローカル環境でフロントエンド(React)からサーバーサイド(Golang)へのPOSTをaxiosとginを用いて行いたいです

発生している問題・エラーメッセージ

axiosのpostが実行されるとstatus code 404 になります

OPTIONS http://localhost:4000/api/post 404 (Not Found) Access to XMLHttpRequest at 'http://localhost:4000/api/post' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. createError.js:17 Uncaught (in promise) Error: Network Error at createError (createError.js:17) at XMLHttpRequest.handleError (xhr.js:80)
Request URL: http://localhost:4000/api/post Request Method: OPTIONS Status Code: 404 Not Found Remote Address: [::1]:4000 Referrer Policy: no-referrer-when-downgrade Content-Length: 18 Content-Type: text/plain Date: Wed, 10 Jul 2019 17:36:01 GMT Provisional headers are shown Access-Control-Request-Headers: content-type Access-Control-Request-Method: POST Origin: http://localhost:3000 Referer: http://localhost:3000/post/finish User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

該当のソースコード

React

1import React from 'react'; 2import {Form, Container} from 'semantic-ui-react'; 3import axios from 'axios'; 4import {Redirect, withRouter} from 'react-router'; 5 6interface ArticleState { 7 title: string; 8 content: string; 9 redirect: boolean; 10} 11 12class Post extends React.Component<{}, ArticleState> { 13 constructor(props: {}) { 14 super(props); 15 this.state = { 16 title: '', 17 content: '', 18 redirect: false, 19 }; 20 21 this.handleChangeTitle = this.handleChangeTitle.bind(this); 22 this.handleChangeContent = this.handleChangeContent.bind(this); 23 this.setRedirect = this.setRedirect.bind(this); 24 this.renderRedirect = this.renderRedirect.bind(this); 25 } 26 27 handleChangeTitle(e: React.FormEvent<HTMLInputElement>) { 28 this.setState({title: e.currentTarget.value}); 29 } 30 31 handleChangeContent(e: React.FormEvent<HTMLInputElement>) { 32 this.setState({content: e.currentTarget.value}); 33 } 34 35 setRedirect() { 36 this.setState({ 37 redirect: true, 38 }); 39 40 const data = {title: this.state.title, content: this.state.content}; 41 axios.post('http://localhost:4000/api/post', data).then(res => { 42 console.log(res); 43 }); 44 } 45 46 renderRedirect = () => { 47 if (this.state.redirect) { 48 return <Redirect to="/post/finish" />; 49 } 50 }; 51 52 render() { 53 return ( 54 <Container text style={{marginTop: '3em'}}> 55 <Form onSubmit={this.setRedirect}> 56 <Form.Input 57 label="Title" 58 placeholder="" 59 name="title" 60 value={this.state.title} 61 onChange={this.handleChangeTitle} 62 /> 63 <Form.Field 64 label="Content" 65 placeholder="" 66 name="content" 67 value={this.state.content} 68 rows="20" 69 control="textarea" 70 onChange={this.handleChangeContent} 71 /> 72 {this.renderRedirect()} 73 <Form.Button content="Submit" /> 74 </Form> 75 </Container> 76 ); 77 } 78} 79 80export default Post; 81

Golang

1package main 2 3import ( 4 "database/sql" 5 "log" 6 "net/http" 7 8 "github.com/gin-gonic/gin" 9 _ "github.com/go-sql-driver/mysql" 10) 11 12type Article struct { 13 ID int `json:"id"` 14 TITLE string `json:"title"` 15 CONTENT string `json:"content"` 16} 17 18var articles []Article 19 20func main() { 21 22 db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/article") 23 if err != nil { 24 panic(err.Error()) 25 } 26 defer db.Close() 27 28 err = db.Ping() 29 if err != nil { 30 panic(err.Error()) 31 } 32 33 router := gin.Default() 34 35 api := router.Group("/api") 36 { 37 api.POST("/post", func(c *gin.Context) { 38 var article Article 39 c.BindJSON(&article) 40 c.Header("Content-Type", "application/json") 41 c.Header("Access-Control-Allow-Origin", "*") 42 c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") 43 ins, err := db.Prepare("INSERT INTO articles(title,content) VALUES(?,?)") 44 if err != nil { 45 log.Fatal(err) 46 } 47 ins.Exec(article.TITLE, article.CONTENT) 48 c.JSON(http.StatusOK, gin.H{"status": "ok"}) 49 }) 50 } 51 52 router.Run(":4000") 53}

試したこと

試しに以下のcurlを叩いたところ正常にローカルのmysqlテーブルに登録されました

curl -X POST -H "Content-Type: application/json" -d '{"title":"bbb", "content":"bbb"}' localhost:4000/api/post

以上、お手数ですがご教授いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

OPTIONS requestに対応するように修正したところ解決しました。

Golang

1 api.POST("/post", func(c *gin.Context) { 2 c.Header("Content-Type", "application/json") 3 c.Header("Access-Control-Allow-Origin", "*") 4 // add 5 c.Header("Access-Control-Allow-Headers", "Content-Type") 6 var article Article 7 c.BindJSON(&article) 8 ins, err := db.Prepare("INSERT INTO articles(title,content) VALUES(?,?)") 9 if err != nil { 10 log.Fatal(err) 11 } 12 ins.Exec(article.TITLE, article.CONTENT) 13 c.JSON(http.StatusOK, gin.H{"status": "ok"}) 14 }) 15 // add response to OPTIONS 16 api.OPTIONS("/post", func(c *gin.Context) { 17 c.Header("Content-Type", "application/json") 18 c.Header("Access-Control-Allow-Origin", "*") 19 c.Header("Access-Control-Allow-Headers", "Content-Type") 20 c.JSON(http.StatusOK, gin.H{"status": "ok"}) 21 })

同内容の質問をstackoverflowにして解決に至りました。

投稿2019/07/10 19:42

編集2019/07/10 19:44
jpskgc

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

set0gut1

2019/07/10 20:02

OPTIONSリクエストに対応するエンドポイントはcors設定をちゃんとやると生えるものなので、gin-gonicの機能を自然に使ったほうが楽だろうとは思います。あと Access-Control-Allow-Origin: * は全アクセス元許可の意なので、ちゃんとフロントエンドとして想定しているhostを入れたほうがセキュリティ的に良いと思います。
guest

0

フロントエンドとバックエンドのhost(hostname+port)が違う場合、特別な設定をしないとブラウザのセキュリティ防御によりリクエストが行われないです。詳細は「CORS」でググるとよくまとまった記事が出てくるのでそちらをご参照ください。

gin-gonicのcors設定は次のあたりに書いてあります。
https://github.com/gin-contrib/cors

今回、開発環境でのアクセス元(ブラウザ側)がlocalhost:3000ということなので、これをAllowOriginsに指定すればオッケーです。
本番環境にデプロイするときにはちゃんと書き換えておく必要があるので注意してください。

投稿2019/07/10 19:27

set0gut1

総合スコア2413

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問