之前的文章《vue3项目生产环境代理方式解决无法配置接口服务器或请求第三方API的cors跨域问题》介绍的nginx配置代理主要是针对API接口,这篇文章解决的是图片跨域问题。图片也是从API接口获得,然后在Vue组件内使用。
<template> <van-swipe class="my-swipe" indicator-color="white" :autoplay="3000" v-if="recommend && recommend.length > 0"> <van-swipe-item v-for="item in recommend" :key="item.did" class="swipe-item"> <img :src="getProxyImageUrl(item.pic)" @click="gotoCover(item.did)" /> <!-- <img :src="item.pic" /> --> </van-swipe-item> </van-swipe> </template> <script setup> import { getProxyImageUrl } from "@/util/index.js" import { computed } from 'vue' const props = defineProps(['recommend']) const recommend = computed(() => props.recommend); import { useRouter } from 'vue-router' const router = useRouter() const gotoCover = (id) => { router.push({ path: `/comicCover/${id}` }) }; </script>
组件内使用方法getProxyUmageUrl处理图片访问方式:
// 图片代理访问 export const getProxyImageUrl = (url) => { if (url.startsWith('https://thirdwx.qlogo.cn/')) { return url; // 直接返回原始 URL } else if (url.startsWith('http://ksyuncomic.9comic.cn/')) { return `/proxy-image${new URL(url).pathname}`; // 返回代理后的 URL } else { return url; // 其他情况直接返回原始 URL } };
经过getProxyUmageUrl方法处理,图片链接类似/proxy-image/comic/2019/03/01/d05e65e1709e488ec8c18b02aabfda75.jpg,再加上网站域名,最后图片完整链接是https://haokan.chaihongjun.me/proxy-image/comic/2019/03/01/d05e65e1709e488ec8c18b02aabfda75.jpg。真实目标图片地址是http://ksyuncomic.9comic.cn/comic/2019/03/01/d05e65e1709e488ec8c18b02aabfda75.jpg。那么就需要在nginx上做对应的代理转发配置:
# 图片代理转发配置 location ^~ /proxy-image { # 将请求代理到实际的图片服务器 rewrite ^/proxy-image(/.*) $1 break; proxy_pass http://ksyuncomic.9comic.cn/; proxy_set_header Host ksyuncomic.9comic.cn; proxy_set_header Referer "http:// ksyuncomic.9comic.cn"; #防止403 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_ssl_server_name on; # 可选:增加缓存控制以减少对图片服务器的压力 # proxy_cache_valid 200 301 302 10m; # proxy_cache_valid 404 1m; # proxy_cache_key $scheme$proxy_host$request_uri; # 设置 CORS 头 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization'; # 确保正确处理重定向 proxy_redirect off; add_header X-Proxy-Debug "Path: $uri => $proxy_host$uri"; add_header X-Debug-Message "Proxied to ksyuncomic.9comic.cn" always; # 可选:设置超时时间 proxy_connect_timeout 60s; proxy_read_timeout 60s; proxy_send_timeout 60s; # 添加日志记录以调试 access_log /alidata1/www/logs/proxy_access.log; error_log /alidata1/www/logs/proxy_error.log; } # API 代理转发 location /reverseproxy { proxy_pass https://apis.netstart.cn/haokan/; proxy_set_header Host apis.netstart.cn; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_ssl_server_name on; proxy_ssl_name apis.netstart.cn; # 设置 CORS 头 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization'; # 处理预检请求(OPTIONS) if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } # 调试信息 add_header X-Debug-Message "Proxied to API" always; } # Vue单页面防止404配置 location / { try_files $uri $uri/ /index.html; }
注意图片代理和API代理那里的区别,图片代理使用^~提升匹配等级,如果只是 location /proxy-image 可能无法进入匹配模式