1. 程式人生 > >Java 解決跨域請求

Java 解決跨域請求

不多說,直接上程式碼。

 

  • 被呼叫方自適應呼叫方請求域
    • 該方法只需要修改被呼叫方的後臺程式碼,呼叫方可依照正常的ajax訪問資料
    • 無序列表我們以spring-boot框架為例子,首先,在後臺建立一個跨域處理過濾器,程式碼如下
      • import org.springframework.util.StringUtils;
        import javax.servlet.*;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.io.IOException;
        
        /**
         * 跨域請求處理
         */
        public class CrosFilter implements Filter {
        
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
        
            }
        
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                HttpServletResponse response = (HttpServletResponse) servletResponse;
                HttpServletRequest request = (HttpServletRequest) servletRequest;
        
                String origin = request.getHeader("Origin");
                if(!StringUtils.isEmpty(origin)){
                    //但請求帶有cookie的時候,origin不能為*,必須是全匹配名
                    response.addHeader("Access-Control-Allow-Origin",origin);
                }
        
                response.addHeader("Access-Control-Allow-Methods","*");
        
                String header = request.getHeader("Access-Control-Allow-Headers");
                //匹配所有自定義請求頭
                if(!StringUtils.isEmpty(header)){
                    response.addHeader("Access-Control-Allow-Headers",header);
                }
        
                //代表著瀏覽器請求第一次之後,一個小時之內可以快取請求資訊,不需要在傳送預檢命令
                response.addHeader("Access-Control-Max-Age","3600");
        
                //當請求帶cookie的時候,需要將Credentials設定為true
                response.addHeader("Access-Control-Allow-Credentials","true");
        
                filterChain.doFilter(servletRequest,servletResponse);
            }
        
            @Override
            public void destroy() {
        
            }
        }

         

    • 下一步是在啟動類裡面配置過濾器
      • import org.mybatis.spring.annotation.MapperScan;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.web.servlet.FilterRegistrationBean;
        import org.springframework.context.annotation.Bean;
        import springfox.documentation.swagger2.annotations.EnableSwagger2;
        
        @SpringBootApplication
        @EnableSwagger2
        @MapperScan("com.vcyber.mapper")
        public class UserApplication {
        
           public static void main(String[] args) {
              SpringApplication.run(UserApplication.class, args);
           }
        
           /**
            * 處理跨域
            * @return
            */
           @Bean
           public FilterRegistrationBean registrationBean(){
              FilterRegistrationBean bean = new FilterRegistrationBean();
        
              bean.addUrlPatterns("/*");
              bean.setFilter(new CrosFilter());
              return bean;
           }
        }

         

    • 到這裡使用過濾器處理跨域請求的方法就完成了,這種方式適用於任務一種請求,實用性比Jsonp要好,推薦使用。
  • spring框架處理跨域
    • 上面我們講的兩種處理方式都是適用後臺任何一種框架,而我們的spring框架提供了一種框架自帶的解決方式。
    • 就是在我們提供被請求的類或者方法上面新增一個@CrossOrigin註解,如:
      • @RestController
        @RequestMapping("loginrecord")
        @CrossOrigin
        public class LoginRecordController {
        }

      • @RestController
        @RequestMapping("loginrecord")
        public class LoginRecordController {
        @GetMapping("getMybatisLoginList")
        @CrossOrigin
        public ResponseData getMybatisLoginList(){
            ResponseData responseData = new ResponseData();
            responseData.setCode("200");
            responseData.setMessage("成功");
            responseData.putDataValue("list",loginRecordMapper.selectList(null));
            return responseData;
        }
        }

         

    • 在類上面加上@CrossOrigin註解,則表示該類裡面的所有方法都支援跨域請求,如果在指定方法上加註解,則說明該方法支援跨域請求
  • Jsonp
    • 前臺使用ajax的jsonp方式訪問請求
      • $.ajax({
        		type:"get",
        		url:"http://localhost:8080/loginrecord/getMybatisLoginList",
        		dataType:"jsonp",
        		jsonp:"callback",
        		success:function(result){
        			alert(result)
        		}

         

    • 後臺需要新增一個JsonP處理類
      • import org.springframework.web.bind.annotation.ControllerAdvice;
        import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
        
        @ControllerAdvice
        public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
        
            public JsonpAdvice(){
                super("callback");
            }
        }

         

    • 注意:1.JsonpAdvice建構函式所返回的資料必須與前端ajax的jsonp屬性資料一致
                 2.Jsonp只支援GET請求,所以面對多種請求方式的時候,不建議使用,可採用別種方式