Проверка user-agent
Возникла необходимость проверить, откуда пользователь делает запрос, чтобы определить, каким способом дать ему ответ(дать html в браезер или JSON в, например, curl). Знаю, что html можно дать и в curl, но это будет неудобоваримо.
Погуглив, узнал, что нет какого-то "железного" способа определить, делается ли запрос из браузера. Но есть некая закономерность в юзерагентах браузеров. Написал мини-функцию и хочу спросить мнения, является ли она хоть сколь-либо надежной, для определения пришел пользователь из браузера или нет и почитать мнение, как можно надежнее определить это. Вот функция:
func GetRequest(w http.ResponseWriter, r *http.Request) {
ua := r.Header.Get("User-Agent")
switch true {
case strings.Contains(ua, "Mozilla"):
w.Write([]byte("Browser" + "\n"))
return
case strings.Contains(ua, "Gecko"):
w.Write([]byte("Browser" + "\n"))
return
default:
w.Write([]byte("Rest quester" + "\n"))
}
}
Добавил еще такой кейс
case strings.Contains(ua, "Opera"):
w.Write([]byte("Browser" + "\n"))
return
Ответы (2 шт):
Попробуйте использовать существующие пакеты для парсинга User-Agent, например https://github.com/mileusna/useragent, https://github.com/mssola/user_agent или https://github.com/ua-parser/uap-go.
Данные пакеты позволяют определить тип браузера, операционную систему, тип устройства и т.д.
Вот пример с перехватом четрыех браузеров (в пакете доступно больше):
package main
import (
"github.com/mileusna/useragent"
"log"
"net/http"
)
func GetRequest(w http.ResponseWriter, r *http.Request) {
useragent := r.Header.Get("User-Agent")
parsed := ua.Parse(useragent)
if parsed.Name == ua.Chrome || parsed.Name == ua.Opera || parsed.Name ==ua.Firefox || parsed.Name == ua.Safari {
// вернуть HTML
} else {
// вернуть JSON
}
}
func main() {
http.HandleFunc("/", GetRequest)
log.Fatal(http.ListenAndServe(":8000", nil))
}
В можете перечислить в if все браузеры, которые заданны в данном пакете. Таким образом вы покроете абсолютное большинство запросов (за исключением кастомных браузеров).
Я думаю, что Ваш подход очень необычен. А что если я в curl хочу получать текст? Или в браузере получать данные в виде json? Но человечество нашло выход.
Самый простой и наивный способ - кодировать тип желаемого результата в самом запросе. Ведь если url/uri содержит index.html, то очевидно, что хотят получить текст в виде html, а если там data.json, то явно не xml ожидают. Этот подход очень "нативный" и "ожидаемый".
Второй способ - клиент явно декларирует в запросе, что он хочет использует для этого заголовок Accept: text/plain (или что именно нужно)
[зачеркнуто] Content-Type может быть не только в ответе, а и в запросе. Вот есть пример https://stackoverflow.com/questions/56722602/golang-http-server-return-html-or-json-depending-on-content-type [/зачеркнуто]