fix: 获取真实请求ip(解决使用docker部署时,ssr请求无法获取用户真实ip的问题,解决方案:转发astro headers)

This commit is contained in:
2026-07-11 23:54:59 +08:00
parent 4dcee7790b
commit 0b9c253402
4 changed files with 57 additions and 12 deletions

View File

@@ -1,12 +1,51 @@
import ky, {type Options} from 'ky'
type ForwardHeaderSource = Headers | Record<string, string | undefined> | undefined | null
const api = ky.create({
baseUrl: import.meta.env.VITE_API_BASE_URL
});
// ApiPageResponse<Post[]>
export const http = {
const pickHeader = (source: ForwardHeaderSource, name: string): string | undefined => {
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> => {
return api.get(url, options).json<T>()
return api.get(url, {
...options,
headers: {
...forwardedHeaders,
...(options?.headers ?? {})
}
}).json<T>()
}
};
}
export const http = createHttp();

View File

@@ -2,9 +2,11 @@
import Layout from "@/layouts/Layout.astro";
import PostList from "@/components/PostList.astro";
import type {Post} from "@/types/post";
import {http} from "@/lib/request";
import {createHttp} from "@/lib/request";
import {metadata} from "@/consts.ts";
const http = createHttp(Astro.request.headers)
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
searchParams: {
page: 1,

View File

@@ -2,7 +2,7 @@
import Layout from "@/layouts/Layout.astro";
import PostList from "@/components/PostList.astro";
import type {Post} from "@/types/post";
import {http} from "@/lib/request";
import {createHttp} from "@/lib/request";
import {metadata} from "@/consts.ts";
const {page} = Astro.params
@@ -11,6 +11,8 @@ if (isNaN(Number(page))) {
return Astro.redirect('/')
}
const http = createHttp(Astro.request.headers)
const {list, total} = await http.get<ApiPageResponse<Post>>("post", {
searchParams: {
page,

View File

@@ -3,7 +3,7 @@ import "github-markdown-css/github-markdown-light.css"
import "@/styles/github-markdown.css"
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 {formatDatetime} from "@/lib/format.ts";
import type {Post} from "@/types";
@@ -12,6 +12,8 @@ const {slug} = Astro.params;
let data: Post;
const http = createHttp(Astro.request.headers)
try {
const res = await http.get<ApiResponse<Post>>(`post/${slug}`);
data = res.data