Skip to content

Commit a510eb2

Browse files
committed
fix ImageUploader bugs
1 parent d46518e commit a510eb2

2 files changed

Lines changed: 30 additions & 33 deletions

File tree

client/nginx.conf

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ server {
2626
}
2727

2828
location /uploads/ {
29-
proxy_pass http://backend:3000;
30-
proxy_set_header Host $host;
31-
proxy_set_header X-Real-IP $remote_addr;
29+
proxy_pass http://backend:3000/uploads/;
30+
proxy_set_header Host $host;
3231
}
3332
}
3433

client/src/components/ImageUploader.vue

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -86,26 +86,36 @@ const dragover = ref(false);
8686
const error = ref("");
8787
const previewUrl = ref("");
8888
89-
// 初始化回显逻辑
89+
const getFullImageUrl = (path) => {
90+
if (!path) return '';
91+
92+
// 1. 如果已经是完整的 http 链接,直接用
93+
if (path.startsWith('http')) return path;
94+
95+
// 2. 如果是静态资源 (/uploads 开头),直接拼域名前缀,不要拼 /api
96+
// 结果会是: https://myshkin451.com/uploads/posts/xxx.jpg
97+
if (path.startsWith('/uploads')) {
98+
return `${window.location.origin}${path}`;
99+
}
100+
101+
// 3. 其他情况才拼 API 地址
102+
const baseUrl = import.meta.env.VITE_API_URL || '';
103+
return `${baseUrl}${path}`;
104+
};
105+
106+
// 初始化回显
90107
onMounted(() => {
91108
if (props.modelValue) {
92-
// 如果是完整 URL 直接用,如果是相对路径则拼上前缀
93-
const isAbsolute = props.modelValue.startsWith('http');
94-
// 注意:这里需要根据你的环境变量调整,如果没有定义 VITE_API_URL,默认用空或后端地址
95-
const baseUrl = import.meta.env.VITE_API_URL || '';
96-
previewUrl.value = isAbsolute ? props.modelValue : `${baseUrl}${props.modelValue}`;
109+
previewUrl.value = getFullImageUrl(props.modelValue);
97110
}
98111
});
99112
100-
// 监听外部 modelValue 变化(例如重置表单时)
113+
// 监听变化
101114
watch(() => props.modelValue, (newVal) => {
102115
if (!newVal) {
103116
previewUrl.value = "";
104117
} else if (newVal !== previewUrl.value) {
105-
// 只有当新值和当前预览不一致时才更新(避免循环)
106-
const isAbsolute = newVal.startsWith('http');
107-
const baseUrl = import.meta.env.VITE_API_URL || '';
108-
previewUrl.value = isAbsolute ? newVal : `${baseUrl}${newVal}`;
118+
previewUrl.value = getFullImageUrl(newVal);
109119
}
110120
});
111121
@@ -124,47 +134,35 @@ const onDrop = (e) => {
124134
};
125135
126136
const handleUpload = async (file) => {
127-
if (!file.type.startsWith("image/")) {
128-
error.value = "File must be an image.";
129-
return;
130-
}
131-
if (file.size > 5 * 1024 * 1024) {
132-
error.value = "File size exceeds 5MB.";
133-
return;
134-
}
137+
// ... (保留你之前的校验逻辑) ...
138+
if (!file.type.startsWith("image/")) { error.value = "File must be an image."; return; }
139+
if (file.size > 20 * 1024 * 1024) { error.value = "File size exceeds 20MB."; return; } // 改成 20M 匹配服务器设置
135140
136-
error.value = "";
137141
uploading.value = true;
142+
error.value = "";
138143
139144
try {
140145
const fd = new FormData();
141-
// 根据你的 API 定义调整字段名
142146
const fieldName = props.uploadType === 'avatar' ? 'avatar' : 'image';
143147
fd.append(fieldName, file);
144148
145149
let res;
146150
if (props.uploadType === 'avatar') {
147151
res = await api.uploadAvatar(fd);
148152
} else {
149-
// 默认使用通用的图片上传,返回 { url, path }
150153
res = await api.uploadPostImage(fd);
151154
}
152155
153-
// 解析返回值:你的 API 返回 { url, path }
154-
// url: 绝对路径 (用于预览)
155-
// path: 相对路径 (用于存库)
156156
const { url, path } = res;
157-
158-
// 更新预览
159-
previewUrl.value = url;
160157
161-
// 向父组件更新值 (通常存 path 到数据库比较灵活)
158+
// 更新预览 (使用 path 走一遍 getFullImageUrl 逻辑,或者直接用 url)
159+
previewUrl.value = url;
162160
emit("update:modelValue", path);
163161
emit("upload-success", url);
164162
165163
} catch (err) {
166164
console.error(err);
167-
error.value = "Upload failed. Please try again.";
165+
error.value = "Upload failed.";
168166
emit("upload-error", err);
169167
} finally {
170168
uploading.value = false;

0 commit comments

Comments
 (0)