Javascript fetch () проверяет мою конечную точку отдыха golang более одного раза? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть ошибка, которую я не понимаю, если я делаю что-то не так с Golang или я делаю что-то не так с оператором javascript fetch().Это простая ситуация, когда я хочу сделать fetch() вызов конечной точки golang и просто напечатать hello world.Но по какой-то причине код Голанга запускается дважды.Вот мой код:

// main.go

package main

import (

  "route/page"
  "github.com/gorilla/mux"
  "log"
  "net/http"
)

func main() {

    router := mux.NewRouter()
    router.HandleFunc("/page", page.Search).Methods("GET","OPTIONS")
    log.Fatal(http.ListenAndServe(":8000", router))

}


//route/page.go

package page
import (
  "net/http"
  "log"
)

func Search(w http.ResponseWriter, r *http.Request) {

  w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization, Organization")
  w.Header().Set("Access-Control-Allow-Origin", "*")
  w.Header().Set("Content-Type", "application/json")

  log.Println(r.Header.Get("authorization"))

  log.Println("Hello World")
  w.Write([]byte("{}"))
  return
}

Затем я пошел на JSFiddle.net и вставил следующий код JS и нажал Run:

fetch('http://192.168.0.21:8000/page', {
  method: 'GET',
  headers: {
    'Content-Type': 'text/plain',
    'Organization': 'afae3@@@@@%2Fajfoij',
    'Authorization': 'Basic tajoie#$@asdfall%DF;++JI%2F3255',
  }
})

И по какой-то причине моя консоль дважды печатает Hello Worldнапример:

john@ubuntu:~/go/src/myproject$ go run main.go
2018/09/20 18:42:29
2018/09/20 18:42:29 Hello World
2018/09/20 18:42:29 Basic tajoie#$@asdfall%DF;++JI%2F3255
2018/09/20 18:42:29 Hello World

Я переписал свой JS-код в PHP, поместил свой PHP-код на тот же локальный хост, что и мой код golang, запустил PHP-код из консоли и получил ожидаемый результат выполнения кода golang.только однажды.Кто-нибудь знает, что происходит?Я что-то неправильно понял о fetch()?Что-то необычное происходит с тем, как я устанавливаю заголовки?

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

Это расширение ответа spencedev

. Как подсказывает пользователь rmn , в данной статье проводится различие между концепцией "простого запроса" и "непростой запрос "с точки зрения CORS:

https://codeburst.io/cors-story-of-requesting-twice-85219da7172d

Наличие Authorization и Organization в моем заголовке делает мой HTTP-запрос" непростым запросом "с точки зрения CORS, и заставляет fetch() инициировать как запрос GET, так и запрос OPTION, причем запрос OPTION известен как предполетный запрос CORS.Как указал spencedev, мой код golang

router.HandleFunc("/page", page.Search).Methods("GET","OPTIONS")

говорит, что page.Search должен обрабатывать запросы GET и OPTIONS.

Как указал sberry , гориллаВ библиотеке есть пакет для работы с CORS.Альтернатива ответу spencedev с использованием обработчика Gorilla CORS находится ниже

// main.go
package main

import (

  "route/page"
  "github.com/gorilla/mux"
  "github.com/gorilla/handlers"
  "log"
  "net/http"
)

func main() {

    router := mux.NewRouter()

    router.HandleFunc("/page", page.Search).Methods("GET")

    headersOk := handlers.AllowedHeaders([]string{"Content-Type","Authorization","Organization"})
    originsOk := handlers.AllowedOrigins([]string{"*"})
    methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
    log.Fatal(http.ListenAndServe(":8000", handlers.CORS(originsOk, headersOk, methodsOk)(router)))

}

// route/page.go
package page
import (
  "net/http"
  "log"
)


func Search(w http.ResponseWriter, r *http.Request) {

  log.Println(r.Header.Get("authorization"))

  log.Println("Hello World")
  w.Write([]byte("{}"))
  return
}
0 голосов
/ 07 декабря 2018

Чтобы включить CORS для всех API, вам нужно обработать предполётный запрос.

import (
  "log"
  "net/http"
  "github.com/gorilla/mux"
)

func main() {
  router := mux.NewRouter()

  // Handle all preflight request for CORS
  router.Methods("OPTIONS").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Methods", "*")
    w.Header().Set("Access-Control-Allow-Headers", "*")
    w.WriteHeader(http.StatusNoContent)
    return
  })

  // Your route handlers goes right here
  router.HandleFunc("/page", page.Search).Methods("GET")

  log.Fatal(http.ListenAndServe(":3000", router))
}
0 голосов
/ 21 сентября 2018
router.HandleFunc("/page", page.Search).Methods("GET","OPTIONS")

Указывает маршрутизатору направить оба метода GET и OPTIONS в обработчик поиска.

Предварительный просмотр CORS , обычно , обрабатывается отдельным обработчиком.В вашем случае вы говорите Go обработать предполетную проверку и запрос на получение с помощью обработчика поиска.

Обычно вы хотите обрабатывать предполетную проверку отдельно от последующей по запросу, поэтомузапрос не выполняется дважды (один раз без причины.)

Чрезвычайно простая версия обработчика перед полетом будет:

func PreFlightHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://localhost")
    w.Header().Set("Vary", "Origin")
    w.Header().Set("Vary", "Access-Control-Request-Method")
    w.Header().Set("Vary", "Access-Control-Request-Headers")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Origin, Accept")
    w.Header().Set("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
    w.Header().Set("Access-Control-Allow-Credentials", "true")
}

Полный код Голанга будет:

// main.go

package main

import (

  "route/page"
  "github.com/gorilla/mux"
  "log"
  "net/http"
)

func main() {

    router := mux.NewRouter()
    router.HandleFunc("/page", page.PreFlightHandler).Methods("OPTIONS")

    router.HandleFunc("/page", page.Search).Methods("GET")

    log.Fatal(http.ListenAndServe(":8000", router))

}

// route/page.go
package page
import (
  "net/http"
  "log"
)

func PreFlightHandler(w http.ResponseWriter, r *http.Request) {

    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Vary", "Origin")
    w.Header().Set("Vary", "Access-Control-Request-Method")
    w.Header().Set("Vary", "Access-Control-Request-Headers")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Origin, Accept, Authorization, Organization")
    w.Header().Set("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
    w.Header().Set("Access-Control-Allow-Credentials", "true")
}
func Search(w http.ResponseWriter, r *http.Request) {

  log.Println(r.Header.Get("authorization"))

  log.Println("Hello World")
  w.Write([]byte("{}"))
  return
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...