徹底解決跨域問題

跨域校驗(yàn)是瀏覽器的行為妥泉,旨在提升不同站點(diǎn)訪問的安全性椭微。在提升安全性的同時(shí)也增加了開發(fā)者的開發(fā)難度,為了解決跨域問題盲链,開發(fā)者們想出了一些列解決方案蝇率,來允許跨域(更確切地說是在可控范圍內(nèi)允許跨域)。在前后端分離流行的今天刽沾,前端和后端都發(fā)展出了解決跨域的方法本慕,本篇文章主要講解后端的跨域解決方案。

1侧漓、跨域問題本地測試

在本地搭建前端锅尘、后端服務(wù),用花生殼做內(nèi)網(wǎng)穿透布蔗,前端接口調(diào)用指向穿透鏈接藤违。即可模擬跨域場景,同時(shí)也可以在本地調(diào)試纵揍《倨梗【只要端口不同,不用做內(nèi)網(wǎng)穿透也是可以重現(xiàn)跨域場景的】


image.png

2泽谨、服務(wù)端跨域解決方案

新增filter璧榄,設(shè)置響應(yīng)header的跨域參數(shù)特漩。
參數(shù)包括:
Access-Control-Allow-Origin:允許跨域的請求發(fā)起源網(wǎng)站。不要粗暴的寫成"*"骨杂,要從請求頭中獲取origin涂身,明確具體的來源。
Access-Control-Allow-Credentials:允許客戶端攜帶驗(yàn)證信息搓蚪。若前端設(shè)置了withCredentials: true則此處必須設(shè)置為true访得。
Access-Control-Allow-Methods:允許跨域的方法。GET\POST\PUT\DELETE
Access-Control-Max-Age
Access-Control-Allow-Headers

在解決跨域問題時(shí)也要注意瀏覽器的提示陕凹,有的放矢,不要胡亂猜測鳄炉,一通操作杜耙。

The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '' when the request's credentials mode is 'include'.

image.png

檢查Access-Control-Allow-Origin是否設(shè)置成
,改成具體的前端網(wǎng)址地址拂盯,或者((HttpServletRequest) servletRequest).getHeader("origin")即可佑女。

The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.


image.png

檢查Access-Control-Allow-Credentials是否設(shè)置成true。

3谈竿、復(fù)雜請求put和delete的跨域解決方案

有些同學(xué)設(shè)置了跨域后团驱,發(fā)現(xiàn)put和delete依然存在跨域,其原因是put和delete為復(fù)雜請求空凸,復(fù)雜請求會先發(fā)起options請求嚎花,判斷服務(wù)器是否支持后續(xù)的請求,所以不能簡單的return呀洲,return前需要將put紊选,delete等配置好跨域。見代碼中的setHeader方法道逗。

4兵罢、代碼

隨便找個(gè)目錄放進(jìn)去就可以了。

package pro.haichuang.ktwelve.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.IOException;

import org.springframework.http.HttpStatus;
import pro.haichuang.ktwelve.util.L;

@Configuration
@Order(value = 0)
@WebFilter(filterName = "CorsFilterConfig", urlPatterns = "/*")
public class CorsFilterConfig implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        L.i(new Throwable().getStackTrace()[0] + "===============CorsFilterConfig執(zhí)行=================");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        String origin = ((HttpServletRequest) servletRequest).getHeader("origin");
        res.setHeader("Access-Control-Allow-Origin", origin);
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Max-Age", "1728000");
        res.setHeader("Access-Control-Allow-Headers", "Authentication, Authorization, content-type, Accept, x-requested-with, Cache-Control");
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;

        String requestMethod = httpRequest.getMethod();
        if (requestMethod.equals(RequestMethod.OPTIONS.name())) {
            setHeader(httpRequest, httpResponse);
            return;
        }
        filterChain.doFilter(servletRequest, res);
    }

    private void setHeader(HttpServletRequest request, HttpServletResponse response) {
        //跨域的header設(shè)置
        String origin = request.getHeader("origin");
        response.setHeader("Access-Control-Allow-Origin", origin);
        //這句可以解決當(dāng)請求為put和delete時(shí)的跨域問題
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        //防止亂碼滓窍,適用于傳輸JSON數(shù)據(jù)
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        response.setStatus(HttpStatus.OK.value());
    }

    @Override
    public void destroy() {
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卖词,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吏夯,更是在濱河造成了極大的恐慌此蜈,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噪生,死亡現(xiàn)場離奇詭異舶替,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杠园,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門顾瞪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事陈醒√璩龋” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵钉跷,是天一觀的道長弥鹦。 經(jīng)常有香客問我,道長爷辙,這世上最難降的妖魔是什么彬坏? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮膝晾,結(jié)果婚禮上栓始,老公的妹妹穿的比我還像新娘。我一直安慰自己血当,他們只是感情好幻赚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著臊旭,像睡著了一般落恼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上离熏,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天佳谦,我揣著相機(jī)與錄音,去河邊找鬼滋戳。 笑死吠昭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胧瓜。 我是一名探鬼主播矢棚,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼府喳!你這毒婦竟也來了蒲肋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤钝满,失蹤者是張志新(化名)和其女友劉穎兜粘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弯蚜,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孔轴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碎捺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片路鹰。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贷洲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晋柱,到底是詐尸還是另有隱情优构,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布雁竞,位于F島的核電站钦椭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碑诉。R本人自食惡果不足惜彪腔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望进栽。 院中可真熱鬧德挣,春花似錦、人聲如沸泪幌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祸泪。三九已至,卻和暖如春建芙,著一層夾襖步出監(jiān)牢的瞬間没隘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工禁荸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留右蒲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓赶熟,卻偏偏與公主長得像瑰妄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子映砖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容