這周接了一個會議管理系統那裏練手,也是本身負責的第一個項目,從需求分析,數據庫的設計,到開始動手搭框架些項目,都是都對前面學習的一次整合。html
後臺在開發接口時,使用postman測試時,接口均可以正常完成功能,因此就放到了服務器上給前端測試。在測試時問題就出來了;前端
後臺:ssm+shiro框架vue
前端:vue.jsios
問題描述:git
該項目的登陸先由後臺生成一驗證碼返回給前端,並保存在session中,不過當前端登陸時,後臺會報 NullPointerException,看前端的請求頭才發現前端的請求中並無攜帶cookie信息,並且會發生幾回請求;github
開始咱們覺得這就是經典的跨域問題,而後我就去了解了跨域web
什麼是跨域ajax
瀏覽器從一個域名的網頁去請求另外一個域名的資源時,域名、端口、協議任一不一樣,都是跨域
spring
域名: 數據庫
1. 端口和協議的不一樣,只能經過後臺來解決
2. localhost和127.0.0.1雖然都指向本機,但也屬於跨域
爲何會有跨域
由於瀏覽器的同源策略:
同源策略限制了從同一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。
無論怎麼樣,咱們都是須要同源策略的,那麼如何解決跨域了,先後端都有本身的解決方案,
解決跨域
先後端都有本身的解決方案,前端有jsonp專門用於解決跨域,無論只能使用get請求,很不方便;因此後端解決跨域會方便一些
CORS
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。看名字就知道這是處理跨域問題的標準作法。CORS背後的基本思想是使用自定義的HTTP頭部容許瀏覽器和服務器相互瞭解對方,從而決定請求或響應成功與否
Access-Control-Allow-Origin:指定受權訪問的域Access-Control-Allow-Methods:受權請求的方法(GET, POST, PUT, DELETE,OPTIONS等)複製代碼
在後臺我經過spring mvc的攔截器去實現:
在spring-mvc-xml配置自定義攔截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.cqupt.meeting.interceptor.ResponseInterceptor" />
</mvc:interceptor></mvc:interceptors>複製代碼
後臺配置完成後,問題仍然沒有解決,我再次查看請求,發現每次請求都會有Options方式的請求,下面咱們看看這個options請求是怎麼來的
CORS有兩種請求,簡單請求和非簡單請求:
(1) 同時知足如下兩大條件,就屬於簡單請求:
2. get
3. post
1. Accept
2. Accept-Language
3. Content-Language
4. Last-Event-ID
5. Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
(2)非簡單請求
非簡單請求會發出一次預檢測請求,返回碼是204,預檢測經過纔會真正發出請求,這才返回200。
在 CORS 中,可使用 OPTIONS 方法發起一個預檢請求,以檢測實際請求是否能夠被服務器所接受。預檢請求報文中的Access-Control-Request-Method
首部字段告知服務器實際請求所使用的 HTTP 方法;Access-Control-Request-Headers
首部字段告知服務器實際請求所攜帶的自定義首部字段。服務器基於從預檢請求得到的信息來判斷,是否接受接下來的實際請求。
他的做用是用於試探服務器的響應是否正確,便是否能接受真正的請求,若是在options請求以後獲取到的響應是拒絕性質的,例如500等http狀態,那麼它就會中止第二次的真正請求的訪問,應對這種跨域預檢機制,後臺能夠經過設置Access-Control-Max-Age來控制瀏覽器在多長時間內(單位s)無需在請求時發送預檢請求。
可是到這,前端的session仍是沒有發送過來,這時我以爲這可能不是跨域了,應該是前端配置問題,而後百度後知道,使用axios請求時默認並不會帶上web瀏覽器的cookie,須要進行如下的設置:
// 網絡請求框架
import axios from 'axios'
axios.defaults.withCredentials=true //讓ajax攜帶cookie
Vue.prototype.$http = axios // 這樣設置就能夠在組件內用 this.$http 使用axios了
axios.defaults.baseURL = '' //初始化基礎地址複製代碼
加上後,終於把session傳給後臺了,完成了登陸;
總結:
在與前端及交互過程當中,問題確定是不少的,就好比這個跨域問題,都認爲是對方的的問題,可是在一步步的解決過程當中,問題實際上是雙方的,因此在交互時,面對問題不能相互甩鍋,而是要學會質疑,不但要質疑別人,更重要的是質疑本身。