1. 程式人生 > >Spring Boot使用CORS解決跨域問題

Spring Boot使用CORS解決跨域問題

一、跨域問題描述

Web開發經常會遇到跨域問題,解決方案有:jsonp,iframe,CORS等等。
CORS 與 JSONP 相比:
1、 JSONP 只能實現 GET 請求,而 CORS 支援所有型別的 HTTP 請求。
2、 使用 CORS,開發者可以使用普通的 XMLHttpRequest 發起請求和獲得資料,比起 JSONP 有更好的 錯誤處理。
3、 JSONP 主要被老的瀏覽器支援,它們往往不支援 CORS,而絕大多數現代瀏覽器都已經支援了 CORS。

二、CORS常用的三種解決跨域問題的方法

這裡我僅僅寫出一個需要被跨域訪問的方法,提出了三種解決方案。
需要被跨域訪問的方法:

package com.lemon.springboot.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import
java.util.Map; /** * @author lemon */ @RestController @RequestMapping("/api") public class ApiController { private static final Logger logger = LoggerFactory.getLogger(ApiController.class); // @CrossOrigin({"http://localhost:8081", "http://localhost:8082"}) @RequestMapping("/get") public Map<String, Object> get
(@RequestParam String name) { Map<String, Object> map = new HashMap<>(); map.put("title", "hello world"); map.put("name", name); return map; } }

1、配置全域性跨域訪問解決方案

寫一個配置類,指定可以被跨域訪問的路徑以及可以跨域的主機連結。這樣,8081和8082埠的應用就可以訪問/api後所有的方法或者資源。

package com.lemon.springboot.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * 全域性配置跨域問題
 * @author lemon
 */
@Configuration
public class CustomCorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {

        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                // 設定了可以被跨域訪問的路徑和可以被哪些主機跨域訪問
                registry.addMapping("/api/**").allowedOrigins("http://localhost:8081", "http://localhost:8082");
            }
        };
    }
}

2、第二種全域性設定方法

package com.lemon.springboot.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author lemon
 */
@Configuration
public class CustomCorsConfiguration2 extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 設定了可以被跨域訪問的路徑和可以被哪些主機跨域訪問
        registry.addMapping("/api/**").allowedOrigins("http://localhost:8081", "http://localhost:8082");
    }
}

3、使用@CrossOrigin註解實現細粒度控制(推薦使用)

直接在需要被跨域訪問的方法上加上@CrossOrigin註解就可以實現被跨域訪問。

package com.lemon.springboot.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lemon
 */
@RestController
@RequestMapping("/api")
public class ApiController {

    private static final Logger logger = LoggerFactory.getLogger(ApiController.class);

    @CrossOrigin({"http://localhost:8081", "http://localhost:8082"})
    @RequestMapping("/get")
    public Map<String, Object> get(@RequestParam String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("title", "hello world");
        map.put("name", name);
        return map;
    }
}

這三種配置方法,當其他系統內的資源跨域訪問的時候,就會起作用!