fix: 获取真实请求ip(解决使用docker部署时,ssr请求无法获取用户真实ip的问题,解决方案:转发astro headers)
This commit is contained in:
@@ -1,12 +1,51 @@
|
|||||||
import ky, {type Options} from 'ky'
|
import ky, {type Options} from 'ky'
|
||||||
|
|
||||||
|
type ForwardHeaderSource = Headers | Record<string, string | undefined> | undefined | null
|
||||||
|
|
||||||
const api = ky.create({
|
const api = ky.create({
|
||||||
baseUrl: import.meta.env.VITE_API_BASE_URL
|
baseUrl: import.meta.env.VITE_API_BASE_URL
|
||||||
});
|
});
|
||||||
|
|
||||||
// ApiPageResponse<Post[]>
|
const pickHeader = (source: ForwardHeaderSource, name: string): string | undefined => {
|
||||||
export const http = {
|
if (!source) return undefined
|
||||||
|
if (source instanceof Headers) return source.get(name) ?? undefined
|
||||||
|
return source[name] ?? source[name.toLowerCase()]
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildForwardHeaders = (source: ForwardHeaderSource): Record<string, string> => {
|
||||||
|
const xff = pickHeader(source, 'x-forwarded-for')
|
||||||
|
const realIp = pickHeader(source, 'x-real-ip')
|
||||||
|
const cfIp = pickHeader(source, 'cf-connecting-ip')
|
||||||
|
const ua = pickHeader(source, 'user-agent')
|
||||||
|
const referer = pickHeader(source, 'referer')
|
||||||
|
const host = pickHeader(source, 'host')
|
||||||
|
const proto = pickHeader(source, 'x-forwarded-proto')
|
||||||
|
|
||||||
|
return {
|
||||||
|
...(xff ? {'x-forwarded-for': xff} : {}),
|
||||||
|
...(realIp ? {'x-real-ip': realIp} : {}),
|
||||||
|
...(cfIp ? {'cf-connecting-ip': cfIp} : {}),
|
||||||
|
...(ua ? {'user-agent': ua} : {}),
|
||||||
|
...(referer ? {referer} : {}),
|
||||||
|
...(host ? {host} : {}),
|
||||||
|
...(proto ? {'x-forwarded-proto': proto} : {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createHttp = (forwardHeadersSource?: ForwardHeaderSource) => {
|
||||||
|
const forwardedHeaders = buildForwardHeaders(forwardHeadersSource)
|
||||||
|
|
||||||
|
return {
|
||||||
get: async <T = unknown>(url: string, options?: Options): Promise<T> => {
|
get: async <T = unknown>(url: string, options?: Options): Promise<T> => {
|
||||||
return api.get(url, options).json<T>()
|
return api.get(url, {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...forwardedHeaders,
|
||||||
|
...(options?.headers ?? {})
|
||||||
|
}
|
||||||
|
}).json<T>()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const http = createHttp();
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import PostList from "@/components/PostList.astro";
|
import PostList from "@/components/PostList.astro";
|
||||||
import type {Post} from "@/types/post";
|
import type {Post} from "@/types/post";
|
||||||
import {http} from "@/lib/request";
|
import {createHttp} from "@/lib/request";
|
||||||
import {metadata} from "@/consts.ts";
|
import {metadata} from "@/consts.ts";
|
||||||
|
|
||||||
|
const http = createHttp(Astro.request.headers)
|
||||||
|
|
||||||
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
|
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import PostList from "@/components/PostList.astro";
|
import PostList from "@/components/PostList.astro";
|
||||||
import type {Post} from "@/types/post";
|
import type {Post} from "@/types/post";
|
||||||
import {http} from "@/lib/request";
|
import {createHttp} from "@/lib/request";
|
||||||
import {metadata} from "@/consts.ts";
|
import {metadata} from "@/consts.ts";
|
||||||
|
|
||||||
const {page} = Astro.params
|
const {page} = Astro.params
|
||||||
@@ -11,6 +11,8 @@ if (isNaN(Number(page))) {
|
|||||||
return Astro.redirect('/')
|
return Astro.redirect('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const http = createHttp(Astro.request.headers)
|
||||||
|
|
||||||
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
|
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
page,
|
page,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import "github-markdown-css/github-markdown-light.css"
|
|||||||
import "@/styles/github-markdown.css"
|
import "@/styles/github-markdown.css"
|
||||||
|
|
||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import {http} from "@/lib/request.ts";
|
import {createHttp} from "@/lib/request.ts";
|
||||||
import {highlightHtmlWithJsdom} from "@/lib/highlight.js";
|
import {highlightHtmlWithJsdom} from "@/lib/highlight.js";
|
||||||
import {formatDatetime} from "@/lib/format.ts";
|
import {formatDatetime} from "@/lib/format.ts";
|
||||||
import type {Post} from "@/types";
|
import type {Post} from "@/types";
|
||||||
@@ -12,6 +12,8 @@ const {slug} = Astro.params;
|
|||||||
|
|
||||||
let data: Post;
|
let data: Post;
|
||||||
|
|
||||||
|
const http = createHttp(Astro.request.headers)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await http.get<ApiResponse<Post>>(`post/${slug}`);
|
const res = await http.get<ApiResponse<Post>>(`post/${slug}`);
|
||||||
data = res.data
|
data = res.data
|
||||||
|
|||||||
Reference in New Issue
Block a user