chaihongjun.me

vue3开发的网站部署在nginx上配置代理解决图片跨域问题

之前的文章《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 可能无法进入匹配模式

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»