SpringCloudGateway
简述
Spring Cloud Gateway 是 Spring 社区开发的一个开源项目,它提供了一个简单而有效的方式,在分布式系统中将请求路由到多个微服务。它构建在 Spring Boot 之上,为传统的 Web 应用程序和云原生微服务提供了一个轻量级的反应式 API 网关。
Spring Cloud Gateway 使用熟悉的 Spring 编程模型,并提供了许多内置功能,例如使用 Netflix Eureka 和 Ribbon 进行服务发现和负载均衡、基于 URI 路径、查询参数、标头和其他属性进行请求转发和过滤以及使用 Hystrix 进行断路器。
Spring Cloud Gateway 的一个关键优点是它能够处理大规模的流量,同时提供路由、过滤和安全性能力。它还支持非阻塞 I/O,这使得它成为构建高性能、低延迟系统的理想选择。
总的来说,Spring Cloud Gateway 是管理分布式系统中微服务的强大工具,可以通过一个入口点简化管理多个服务的复杂性。概念
以下是 Spring Cloud Gateway 中的一些重要概念:
1. 路由(Route):指定请求应该被转发到哪个目标地址,可以基于 URI、Header 和其他条件进行路由。
2. 过滤器(Filter):在请求到达目标地址之前,对请求进行修改、验证等处理操作的组件。
3. 谓词(Predicate):定义一个匹配规则,用于判断是否应该将请求转发给该路由。
4. 断路器(Circuit Breaker):当后端服务出现故障时,可以断开与其连接,避免请求阻塞。
5. 限流(Rate Limiting):对请求进行限制,避免过多的流量导致系统崩溃。
6. 加密(Encryption):使用 SSL 或 TLS 等技术对请求进行加密,保障数据传输的安全性。
7. 身份验证(Authentication):验证用户身份的机制,如 OAuth、JWT 等。
8. 授权(Authorization):决定用户是否有权限访问某个资源或执行某个操作的机制,如 RBAC、ABAC 等。
这些概念是 Spring Cloud Gateway 中非常重要的组成部分,开发人员需要深入理解并掌握它们,才能有效地使用 Spring Cloud Gateway 构建高效、可靠的微服务架构。工作流程图
以下是 Spring Cloud Gateway 的工作流程图:
1. 当客户端发送请求时,请求先通过 Spring Cloud Gateway 的网关路由器(Gateway Router)进行路由匹配。
2. 如果路由匹配成功,则请求将被转发到相应的目标地址。
3. 在请求到达目标地址之前,它会经过一系列过滤器(Filters)的处理,对请求进行修改、验证等操作。
4. 如果过滤器中某个操作失败了,请求将被立即拒绝并返回错误信息。
5. 如果请求成功通过所有过滤器的验证,它将被转发到目标地址。
6. 目标地址响应请求后,响应结果再经过一系列过滤器的处理,最终返回给客户端。
整个工作流程非常清晰简单,但每个步骤都非常关键和复杂。开发人员需要深入理解 Spring Cloud Gateway 的路由、过滤器等核心概念,并掌握其使用方法,才能构建出高效、可靠的微服务架构。
注意:
在路由中定义的没有端口的URI,默认会使用80和443作为HTTP和HTTPS URI的端口值。
路由配置简介
Spring Cloud Gateway 配置主要包括两部分:
1.路由配置:用于定义路由规则,将请求转发到指定的目标服务。路由配置使用 YAML 格式定义,包括 ID、URI、Predicate 等属性。
2.过滤器配置:用于在请求到达目标服务之前或响应返回给客户端之前对请求或响应进行处理。过滤器配置支持多个全局过滤器和针对单个路由的过滤器链。
以下是一个基本的 Spring Cloud Gateway 配置示例:spring: cloud: gateway: routes: - id: service-a-route uri: http://localhost:8080 predicates: - Path=/service-a/** filters: - RewritePath=/service-a/(?.*), /${remaining} - id: service-b-route uri: http://localhost:8081 predicates: - Path=/service-b/**
上述配置文件中,定义了两个路由规则,分别将匹配 /service-a/** 和 /service-b/** 的请求转发到 http://localhost:8080 和 http://localhost:8081 对应的服务上。其中,service-a-route 的路由还配置了一个重写路径的过滤器,将 /service-a/xxx 路径重写为 /xxx 。Predicate
Spring Cloud Gateway 内置的 Predicate Factories 如下:
Spring Cloud Gateway 4.0.4 GatewayFilter 示例和简介,以及它们的使用规则:
1.Add Request Header
Add Request Header GatewayFilter 用于向请求头中添加指定的自定义头信息。示例:@Bean public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() { return new AddRequestHeaderGatewayFilterFactory(); } // 添加 X-My-Custom-Header 请求头信息 filters: - AddRequestHeader=X-My-Custom-Header, myValue
这个规则表示在请求头中添加一个名为 X-My-Custom-Header 的自定义头信息,其值为 myValue。Add Request Parameter
Add Request Parameter GatewayFilter 用于向请求中添加指定的查询参数。示例:@Bean public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() { return new AddRequestParameterGatewayFilterFactory(); } // 添加名为 id,值为 123 的查询参数 filters: - AddRequestParameter=id, 123
这个规则表示在请求中添加一个名为 id,值为 123 的查询参数。Add Response Header
Add Response Header GatewayFilter 用于向响应头中添加指定的自定义头信息。示例:@Bean public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() { return new AddResponseHeaderGatewayFilterFactory(); } // 添加 X-My-Custom-Header 响应头信息 filters: - AddResponseHeader=X-My-Custom-Header, myValue
这个规则表示在响应头中添加一个名为 X-My-Custom-Header 的自定义头信息,其值为 myValue。Dedupe
Dedupe GatewayFilter 用于去重,确保相同的请求只会被路由一次。示例:@Bean public DedupeGatewayFilterFactory dedupeGatewayFilterFactory() { return new DedupeGatewayFilterFactory(); } // 对相同的请求进行去重处理 filters: - name: Dedupe
这个规则表示对相同的请求进行去重处理。Hystrix
Hystrix GatewayFilter 用于在请求失败时触发 Hystrix 断路器。示例:@Bean public HystrixGatewayFilterFactory hystrixGatewayFilterFactory() { return new HystrixGatewayFilterFactory(); } // 开启 Hystrix 断路器,并设置相关参数 filters: - name: Hystrix args: name: myCommand fallbackUri: forward:/fallback executionTimeoutInMilliseconds: 5000
这个规则表示开启一个名为 myCommand 的 Hystrix 断路器,当执行超过 5 秒时触发断路器并转发到 /fallback 路径。Map Request Header
Map Request Header GatewayFilter 用于将请求头映射为指定的值。示例:@Bean public MapRequestHeaderGatewayFilterFactory mapRequestHeaderGatewayFilterFactory() { return new MapRequestHeaderGatewayFilterFactory(); } // 将请求头 Authorization 的值映射为 Basic xxx filters: - name: MapRequestHeader args: headerName: Authorization headerValue: Basic xxx
这个规则表示将请求头 Authorization 的值映射为 Basic xxx。Modify Response
Modify Response GatewayFilter 用于修改响应体信息。示例:@Bean public ModifyResponseGatewayFilterFactory modifyResponseGatewayFilterFactory() { return new ModifyResponseGatewayFilterFactory(); } // 修改响应体中匹配的字符串为指定的值 filters: - name: ModifyResponseBody args: regexp: foo replacement: bar
这个规则表示将响应体中所有匹配到的 foo 替换为 bar。Prefix Path
Prefix Path GatewayFilter 用于为请求路径添加指定的前缀。示例:@Bean public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() { return new PrefixPathGatewayFilterFactory(); } // 在请求路径前加上 /myprefix 前缀 filters: - PrefixPath=/myprefix
这个规则表示在请求路径前加上 /myprefixPreserve Host Header
Preserve Host Header GatewayFilter 用于保留原始的主机头信息。示例:@Bean public PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() { return new PreserveHostHeaderGatewayFilterFactory(); } // 保留原始的主机头信息 filters: - name: PreserveHostHeader
这个规则表示在转发请求时保留原始的主机头信息。Preset Response
Preset Response GatewayFilter 用于返回预设的响应体信息。示例:@Bean public PresetResponseGatewayFilterFactory presetResponseGatewayFilterFactory() { return new PresetResponseGatewayFilterFactory(); } // 返回指定的响应状态码和响应体信息 filters: - name: SetStatus args: value: NOT_FOUND - name: PresetResponse args: status: 404 responseBody: "Page Not Found"
这个规则表示设置响应状态码为 NOT_FOUND,然后返回状态码为 404,响应体为 "Page Not Found" 的响应信息。Redirect to
Redirect to GatewayFilter 用于将请求重定向到指定的路径。示例:@Bean public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() { return new RedirectToGatewayFilterFactory(); } // 将请求重定向到 /login 路径 filters: - name: RedirectTo args: status: FOUND url: /login
这个规则表示将请求重定向到 /login 路径。Remove Request Header
Remove Request Header GatewayFilter 用于从请求头中移除指定的头信息。示例:@Bean public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() { return new RemoveRequestHeaderGatewayFilterFactory(); } // 移除名为 X-My-Custom-Header 的请求头信息 filters: - name: RemoveRequestHeader args: headers: X-My-Custom-Header
这个规则表示移除名为 X-My-Custom-Header 的请求头信息。Remove Response Header
Remove Response Header GatewayFilter 用于从响应头中移除指定的头信息。示例:@Bean public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() { return new RemoveResponseHeaderGatewayFilterFactory(); } // 移除名为 X-My-Custom-Header 的响应头信息 filters: - name: RemoveResponseHeader args: headers: X-My-Custom-Header
这个规则表示移除名为 X-My-Custom-Header 的响应头信息。Rewrite Path
Rewrite Path GatewayFilter 用于重写请求路径。示例:@Bean public RewritePathGatewayFilterFactory rewritePathGatewayFilterFactory() { return new RewritePathGatewayFilterFactory(); } // 将 /foo 路径重写为 /bar filters: - name: RewritePath args: regexp: /foo replacement: /bar
这个规则表示将请求路径中所有匹配到的 /foo 替换为 /bar。Retry
Retry GatewayFilter 用于在请求失败时自动重试。示例:@Bean public RetryGatewayFilterFactory retryGatewayFilterFactory() { return new RetryGatewayFilterFactory(); } // 在请求失败时最多重试 3 次 filters: - name: Retry args: retries: 3
这个规则表示在请求失败时最多重试 3 次。Save Session
Save Session GatewayFilter 用于将响应头中的 Set-Cookie 信息保存到请求上下文中。示例:@Bean public SaveSessionGatewayFilterFactory saveSessionGatewayFilterFactory() { return new SaveSessionGatewayFilterFactory(); } // 将响应头中的 Set-Cookie 信息保存到请求上下文中 filters: - name: SaveSession
这个规则表示将响应头中的 Set-Cookie 信息保存到请求上下文中。
17.自定义过滤器
自定义过滤器需要实现 GatewayFilter 接口,并注册到 Spring 应用程序上下文中。
以下是一个自定义过滤器的示例:@Component public class CustomGatewayFilter implements GatewayFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 过滤器逻辑 return chain.filter(exchange); } }
上面的示例中,CustomGatewayFilter 实现了 GatewayFilter 接口,重写了 filter 方法,实现了自己的过滤器逻辑。在方法中,我们可以对请求和响应进行自定义的处理,然后调用 chain.filter(exchange) 将请求传递给下一个过滤器或目标服务。
自定义过滤器注册到 Spring 应用程序上下文的方式有多种,最简单的方式是使用 @Component 注解将其标记为 Spring 组件,然后自动注册到应用程序上下文中。
自定义过滤器也可以使用 @Order 注解或实现 Ordered 接口指定过滤器的执行顺序。@Order 注解的值越小,执行顺序越靠前。
例如:@Component @Order(1) public class CustomGatewayFilter implements GatewayFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 过滤器逻辑 return chain.filter(exchange); } }
上面的示例中,CustomGatewayFilter 的执行顺序为 1。如果有多个自定义过滤器,可以使用不同的 @Order 值指定它们的执行顺序。
除了实现 GatewayFilter 接口外,自定义过滤器还可以实现 GlobalFilter 接口,这样它就会被应用到所有的路由上。GlobalFilter 是一个特殊的 GatewayFilter,在所有的路由中都会执行。
例如:@Component public class CustomGlobalFilter implements GlobalFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 过滤器逻辑 return chain.filter(exchange); } }
上面的示例中,CustomGlobalFilter 实现了 GlobalFilter 接口,并重写了 filter 方法,实现自定义的全局过滤器逻辑。在方法中,我们可以对所有的请求和响应进行自定义的处理,然后调用 chain.filter(exchange) 将请求传递给下一个过滤器或目标服务。
GlobalFilter 也可以使用 @Order 注解或实现 Ordered 接口指定过滤器的执行顺序。
以上就是 Spring Cloud Gateway 过滤器的使用和自定义的示例。通过使用内置的过滤器和自定义的过滤器,我们可以实现灵活高效的网关路由功能。全局过滤器
在Spring Cloud Gateway中,Global Filter是一种特殊类型的过滤器,它能够提供全局层面的功能和行为。
以下是Spring Cloud Gateway 4.0.4中Global Filters的示例和使用规则:
示例
Logging Filter
Logging Filter可以帮助开发人员在请求和响应时打印日志,以便进行调试和排除故障。你可以编写自己的Logging Filter来记录更具体的信息。@Component public class LoggingFilter implements GlobalFilter { private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { logger.info("Path of the request received -> {}", exchange.getRequest().getPath()); return chain.filter(exchange).then(Mono.fromRunnable(() -> { logger.info("Response code -> {}", exchange.getResponse().getStatusCode()); })); } }
Auth Filter
Auth Filter可以帮助你验证请求是否经过授权。这个过滤器可以与Spring Security集成,并允许你使用注释或者配置文件来定义需要保护的URL。@Component public class AuthFilter implements GlobalFilter { private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class); @Autowired AuthenticationManager authenticationManager; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { String path = exchange.getRequest().getPath().toString(); if (path.contains("/api/secure")) { String token = exchange.getRequest().getHeaders().getFirst("Authorization"); if (token == null || token.isEmpty()) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } try { Authentication auth = new UsernamePasswordAuthenticationToken(token, token); authenticationManager.authenticate(auth); } catch (Exception e) { logger.error("Error while authenticating -> " + e.getMessage()); exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } } return chain.filter(exchange); } }
使用规则
在Spring Cloud Gateway中,Global Filter是通过实现org.springframework.cloud.gateway.filter.GlobalFilter 接口来创建的。为了将Global Filter注册到Gateway中,你需要将其声明为Spring Bean,并使用@Order 注解设置其执行顺序。@Component @Order(1) public class MyGlobalFilter implements GlobalFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // filter logic goes here } }
请注意,@Order 注解的值越小,过滤器就越先执行。因此,如果你有多个Global Filter,则它们的执行顺序将按照从小到大的顺序进行。HttpHeadersFilters过滤器
Spring Cloud Gateway的HttpHeadersFilters是一组过滤器,它们可以用于处理HTTP请求和响应的头部。这些过滤器可以让你添加、删除或修改请求和响应头部。
以下是Spring Cloud Gateway 4.0.4中HttpHeadersFilters的示例和使用规则:
示例
Add Response Header Filter
Add Response Header Filter可以在响应头中添加自定义的键值对,从而使其可以由客户端获取到。@Component public class AddResponseHeaderFilter implements HttpHeadersFilter { @Override public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { HttpHeaders headers = new HttpHeaders(); headers.addAll(input); headers.add("X-Custom-Header", "Added By Gateway"); return headers; } }
Strip Response Header Filter
Strip Response Header Filter可以帮助你从响应头中删除指定的键值对。@Component public class StripResponseHeaderFilter implements HttpHeadersFilter { private static final String HEADER_TO_REMOVE = "X-Header-To-Remove"; @Override public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { HttpHeaders headers = new HttpHeaders(); headers.addAll(input); headers.remove(HEADER_TO_REMOVE); return headers; } }
使用规则
要使用HttpHeadersFilters,请将它们声明为Spring Beans,并使用@Order 注解设置它们的执行顺序。然后,在application.yml 或application.properties 文件中配置spring.cloud.gateway.httpheaders.filters 属性以启用过滤器。spring: cloud: gateway: httpheaders: filters: - stripResponseHeaderFilter - addResponseHeaderFilter
请注意,过滤器的顺序很重要。它们按照在spring.cloud.gateway.httpheaders.filters 属性中定义的顺序执行。因此,如果你想确保某些过滤器比其他过滤器先执行,你需要将它们放在前面的位置。TLS/SSL
使用 Spring Cloud Gateway 中的 TLS/SSL,通常需要遵循以下步骤:
1.为您的域创建或获取证书。您可以使用 OpenSSL 等工具生成自签名证书,也可以从受信任的证书颁发机构(CA)获取证书。
2.将证书存储在一个 Java Key Store (JKS) 文件中。您可以使用 keytool 工具将证书导入到 JKS 文件中。keytool -importcert -keystore keystore.jks -storepass password -file your_certificate.crt -alias your_alias在 application.properties 文件中启用 SSL 并使用 JKS 文件:server.ssl.enabled=true server.ssl.key-store-type=JKS server.ssl.key-store=classpath:keystore.jks server.ssl.key-store-password=password server.ssl.key-password=password
在这里,我们指定了要使用的密钥库类型和文件位置以及密码和别名。(可选)根据需要配置其他 SSL 属性,例如要使用的密码套件或协议版本:server.ssl.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 server.ssl.protocol=TLSv1.2定义网关路由规则,例如:spring: cloud: gateway: routes: - id: my_route uri: https://example.com predicates: - Path=/my-service/**
在这里,我们定义了一个名为 my_route 的路由,它将任何路径为 /my-service/** 的请求转发到 https://example.com 。
这些是使用 Spring Cloud Gateway 中的 TLS/SSL 的基本步骤和规则。根据您的需求,您可以进一步自定义和优化 SSL 配置以满足安全性和性能方面的要求。
配置网管的方法
在 Spring Cloud Gateway 4.0.4 中,您可以使用多种方式配置网关路由和过滤器。
以下是一些常用的配置方法:
1.使用 application.yml 或 application.properties 文件
在您的 application.yml 或 application.properties 文件中,您可以使用 spring.cloud.gateway.routes 属性定义路由规则:spring: cloud: gateway: routes: - id: my_route uri: http://localhost:8080 predicates: - Path=/my-service/**
在这里,我们定义了一个名为 my_route 的路由,它将 /my-service/** 路径下的请求转发到 http://localhost:8080 地址。使用 Java DSL
使用 Java DSL 可以编程方式定义路由配置。例如:@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes() .route("my_route", r -> r.path("/my-service/**") .uri("http://localhost:8080")) .build(); }
在这里,我们定义了一个名为 my_route 的路由,它将 /my-service/** 路径下的请求转发到 http://localhost:8080 地址。使用 GatewayFilterFactory
GatewayFilterFactory 是一种可重用的过滤器工厂,可以将其添加到您的路由配置中。例如,如果您想添加一个自定义的 AddHeaderGatewayFilterFactory 过滤器:@Component public class AddHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { @Override public GatewayFilter apply(NameValueConfig config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate() .header(config.getName(), config.getValue()) .build(); return chain.filter(exchange.mutate().request(request).build()); }; } }
然后您可以在路由配置中使用此过滤器:@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder, AddHeaderGatewayFilterFactory addHeaderGatewayFilterFactory) { return builder.routes() .route("my_route", r -> r.path("/my-service/**") .filters(f -> f.filter(addHeaderGatewayFilterFactory.apply(new NameValueConfig("X-My-Header", "my-value")))) .uri("http://localhost:8080")) .build(); }
在这里,我们添加了一个名为 AddHeaderGatewayFilterFactory 的自定义过滤器,并将其应用于 my_route 路由。Micrometer收集路由指标
在 Spring Cloud Gateway 4.0.4 中,您可以使用 Micrometer 库来收集和记录路由指标。
以下是一些常用的配置方法:
1.添加 Micrometer 依赖
在 build.gradle 或 pom.xml 中添加 Micrometer 依赖:dependencies { implementation "org.springframework.boot:spring-boot-starter-actuator" implementation "io.micrometer:micrometer-core:" implementation "io.micrometer:micrometer-registry-prometheus:" }
这里我们使用 Prometheus 作为我们的监控系统,如果你想使用其他系统请替换对应的依赖。配置 Micrometer
在 application.yml 或 application.properties 文件中添加以下配置:management: endpoints: web: exposure: include: prometheus metrics: export: prometheus: enabled: true
这里将 /prometheus 端点暴露出来,并启用了 Prometheus 监控数据导出。您也可以配置其他导出格式和属性。添加 RouteDefinitionRecorder Bean
定义一个名为 RouteDefinitionRecorder 的 Bean,它将通过 Micrometer 来记录所选路由的指标,并将其公开到 /prometheus 端点:@Configuration public class MetricsConfiguration { @Bean public RouteDefinitionRecorder routeDefinitionRecorder(MeterRegistry meterRegistry) { return new RouteDefinitionRecorder(meterRegistry, "gateway"); } }
此处,我们传递了 MeterRegistry 和一个名为 "gateway" 的前缀。记录所选路由的指标
在您的路由定义中,您可以使用前缀和其他属性来记录指标:@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder, RouteDefinitionRecorder routeDefinitionRecorder) { return builder.routes() .route("my_route", r -> r.path("/my-service/**") .filters(f -> f.stripPrefix(1)) .uri("http://localhost:8080")) .build() .doOnRoute(routeDefinitionRecorder.route("my_service")); }
这里我们调用了 doOnRoute 方法,并传递了一个名为 my_service 的前缀。
这些是使用 Micrometer 来跟踪 Spring Cloud Gateway 路由指标的基本步骤。通过使用 Micrometer,您可以收集并监控诸如请求时间、错误率等指标,从而更好地了解和优化您的网关服务。CORS
CORS 过滤器来解决跨域资源共享的问题。在路由规则中,您可以使用addResponseHeader 方法来添加 Access-Control-Allow-* 头部,从而控制跨域访问。以下是一个简单的示例:@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes() .route("cors_route", r -> r.path("/api/**") .filters(f -> f.addResponseHeader("Access-Control-Allow-Origin", "*")) .uri("http://localhost:8080")) .build(); }
在这个示例中,我们创建了一个名为 cors_route 的路由,并将其应用于 /api/** 的请求路径。我们添加了一个过滤器,它会添加一个名为 Access-Control-Allow-Origin 的头部,值为 * ,表示允许任何来源进行跨域访问。
除了 Access-Control-Allow-Origin ,您还可以添加其他的 CORS 相关头部,例如 Access-Control-Allow-Methods 和 Access-Control-Allow-Headers 。这些头部可以根据您的需求进行配置,以更好地控制跨域访问。
请注意,CORS 是一项重要的安全机制,如果不正确地配置,可能会导致安全漏洞。因此,请确保您的 CORS 配置符合最佳实践,并且仅允许可信的来源进行跨域访问。
iQOONeo5S和iQOONeo5SE到底有什么不同?iQOONeo5还值得购买吗?iQOO在年底选择更新了Neo系列,我本以为会推出iQOONeo6,没想到iQOO跟5这个数字杠上了,不仅推出了iQOONeo5S还连带推出一款LCD屏的iQOONeo5SE。那么
宝可梦GO庆祝游戏推出五周年官方分享5张全新插画宠物养成对游戏宝可梦GO官方为庆祝发售五周年,在7月举办了庆典活动,今日官方在推特公开了5张游戏的全新艺图,这是邀请了5位插画家分别绘制的,作者包括SUSHIO浅野TAO田中寛崇。
打开一本书,就是一个神奇的世界有一天,学校给一年级的孩子留了一个画画作业,孩子刚刚学过一篇课文四个太阳,老师为了让孩子们更好地理解四季的特点,布置了一个有趣的作业画出心中的太阳,让同学们充分发挥想象力,会画出什
来到白鹿原眼睛湿润了,终于明白它获茅盾文学奖之坎坷今天上午高速驱车来到了白鹿原。这里虽不是本次旅行的目的地,但是让我内心是十分激动,影视里的镜头一幅幅画面不断在我脑海里滚动,五味杂陈涌上心头。有感而发一片土黄色的大地上,攒满了土黄
爸爸去哪儿5位爸爸,4个翻车,只有森碟爸爸口碑好五位爸爸通过这档亲子节目和孩子们的互动中建立了浓厚的父子感情,八年里他们也都长大了,家庭生活也都各自的变化,五个爸爸,两个爸爸离婚,两个爸爸口碑受损。只有森碟爸爸田亮口碑最好一家四
神秘买家6亿元拍走,乐视大厦究竟归谁?2014这一年,贾跃亭还是人生得意,乐视系估值高达3000亿元,贾跃亭去了趟美国决定造车构筑更大的生态,双胞胎女儿降生,老贾还买下了一处大楼,冠名乐视大厦。不同于其他互联网公司要么
刘润边界感的本质,是对所有权的认知底层逻辑是润米咨询创始人微软前战略合作总监5分钟商学院主理人刘润提出的概念。他认为,只有掌握了环境背后的底层逻辑,探寻到了万变中的不变,才能在千变万化的世界中看清本质,学会批判性思
侵犯专利被罚1。6亿扯下格力遮羞布,董明珠该反省了格力提起格力大家会想到什么?核心技术,国产骄傲,制造业标杆一系列的印象都在提醒你格力在技术上的强大。但是事实果真如此吗?随着格力被奥克斯起诉专利侵权并被判赔偿1。67亿之后,格力以
股市崩盘有三个前兆每一轮牛市都是人性的疯狂见顶正当人们疯狂的买进追涨杀高往往是危机开启之时但凡有10年以上的交易经验的都经历过两轮牛熊交替两波市场行情历历在目对于散户来说是否能够完全逃离其实在某些征
我国喜马拉雅山是怎样形成的耸立在青藏高原南缘的喜马拉雅山,是世界上最高大雄伟的山脉。它东西绵延2450千米,南北宽200350千米,是由4列平行山脉组成的略向南凸的巨大弧形山系。中国科学家在珠穆朗玛峰地区考
解读细胞死亡续一杨毅编译(接续上一期)用一种特殊的试剂盒,可以测定能量释放时的化学发光量,从而定量分析ATP和ADP的比值。此外,还可用荧光的方法来定量探测细胞毒性。一家分子生物学公司开发了一种双染色的试
端午节爬青城山9点从家出发。2个小时的车程堵成了3个小时,吃午饭一个小时。2点过进入景区。坐了一段缆车到山中央。爬到山顶下午6点左右。下山2个小时。坐观光车出景区都堵了差不多一个小时,本来10分
凭祥边关端午节的地摊草药街见闻凭祥市广场草药街图景位于祖国南疆边陲的凭祥市,是一座美丽的口岸城市,有着令人神往的异国情调,还有那迷人边疆的古战场遗址,雄伟的友谊关城楼。但是最令人难忘的,还是凭祥端午节的草药街了
端午节家宴,推荐八道硬菜,做法简单,下酒下饭,家人喜欢端午节快到了,现在是非常时期,不少人开始规划三天的小长假和家人吃什么?虽然是盛夏,天气还不算太热,属于不冷不热的季节,也是胃口很好的季节,吃啥都嘛嘛香了。假如你宅在家中,就可以和家
端午节放假,推荐12道菜,家宴待都适合,寓意红红火火事事吉祥导语2022年端午假期确定了,家宴推荐12道家常菜,寓意红红火火事事顺意。端午节放假,推荐12道菜,家宴待都适合,寓意红红火火事事吉祥端午节是我国重要的传统节日,它跟春节,中秋并称
孕妇吃粽子佩戴香囊端午节饮食有哪些禁忌?又是一年五月五,门插艾,香满堂,吃粽子,撒白糖,在一声声端午安康中,传递着延续千年的祝福与祈愿。中国端午节的习俗源远流长,可各地民间都流传着不一样的风俗。准妈妈在端午节期间,并不能
端午节,大鱼大肉太腻,试试这6道素食家常菜!清爽不腻味道好明天就是一年一度的端午节了,其实在我们国家,每一个重要的节日都和吃息息相关,每一个重要的节日也是在提醒我们,要根据节气的变化时间的推移调整饮食调养身心。冬天多吃肉主要是为了储备能量
端午节快乐端午小假期要到喽,相信很多人都期盼着,终于可以放松一下了。那大家有想好去哪里玩去哪里吃美食了吗?端午节,又称端阳节龙舟节重午节龙节正阳节天中节等,节期在农历五月初五,是中国民间的传
救命!国产剧竟然这么敢拍?国产网剧已经这么卷了吗?!追暗夜行者时,一度怀疑自己在看院线大片。爆炸场面一波接一波很多都是实景拍摄,有车它是真敢炸啊危险动作,文明小车切勿模仿枪战交火也毫不含糊,激烈逼真,仿佛能
这档综艺绝了,浙江卫视又拿出一张收视王牌不得不承认,浙江卫视的娱乐风标越来越多元化。从2019年中国好声音开始,周深张碧晨等实力歌手从这里出道成名,之后又有天赐的声音闪光乐队等优质音乐综艺出现。浙江卫视已经把音综节目做到
马布里即将从北京北控下课原因浮出水面,不是待遇,也不是战术马布里即将从北京北控下课原因浮出水面,不是待遇,也不是战术。那么是什么原因呢?网友热议一针见血地指出北控两个赛季已经在季后赛的边缘,都是第13名只差一名就可以进入季后赛,无奈被CB
恭喜!勇士总决赛G1双喜临门,73后卫有望复出,科尔公布新消息北京时间6月2日,NBA季后赛正在进行,其中斯玛特表示,对阵斯蒂芬库里克莱汤普森这轮系列赛,睡眠真的很重要,防他们必须时时刻刻跑起来,布鲁克林篮网今天必须抉择是否将76人今年的首轮