You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Swagger生成服务器URL时使用主机名而非IP?

解决Swagger服务器URL自动使用主机名而非IP的问题

核心思路

让Swagger动态读取当前请求的主机名、协议及端口,而非硬编码或默认取服务器IP,这样多环境下无需修改配置,还能避免因IP/主机名不一致导致的CORS问题。

方案1:Spring Boot + Springdoc OpenAPI(主流新版)

通过自定义ServerProvider实现动态服务器URL:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springdoc.core.customizers.ServerProvider;
import jakarta.servlet.http.HttpServletRequest;

@Configuration
public class SwaggerConfig {

    @Bean
    public ServerProvider customServerProvider() {
        return request -> {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest req = attributes.getRequest();
                String scheme = req.getScheme();
                String host = req.getServerName();
                int port = req.getServerPort();
                String basePath = req.getContextPath();
                // 拼接完整服务器URL
                String serverUrl = scheme + "://" + host + (port == 80 || port == 443 ? "" : ":" + port) + basePath;
                return serverUrl;
            }
            //  fallback到默认逻辑
            return null;
        };
    }
}

方案2:Spring Boot + Springfox(旧版Swagger 2/3)

配置Docket时动态设置host:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import jakarta.servlet.http.HttpServletRequest;

@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String host = null;
        if (attributes != null) {
            HttpServletRequest req = attributes.getRequest();
            String scheme = req.getScheme();
            String serverName = req.getServerName();
            int port = req.getServerPort();
            host = scheme + "://" + serverName + (port == 80 || port == 443 ? "" : ":" + port);
        }

        return new Docket(DocumentationType.SWAGGER_2)
                .host(host)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.your.package"))
                .paths(PathSelectors.any())
                .build();
    }
}

额外注意事项

  • 如果使用Nginx等反向代理,必须配置传递Host头,否则Swagger无法获取正确的主机名:
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
    }
    
  • 若仍存在CORS问题,需在Spring中配置全局CORS规则,比如:
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CorsConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOriginPatterns("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
    }
    

内容的提问来源于stack exchange,提问作者mtmx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:12:38