天天看點

前後端分離解決跨域問題:springboot做後端+vue做前端前端部分:後端部分:

簡單描述一下項目情況:

我們目前暫時是在本地電腦上不同localhost端口直接實作跨域,請求資料。這麼簡簡單單的問題。我花了好多時間去查資料。結果沒想到很簡單就實作了。

前端部分:

使用axios擷取後端資料:

1.安裝axios:

npm install axios
           

2.main.js中導入

  import axios from 'axios';

  Vue.prototype.$http = axios;

  (注意:不使用use來使用該例,而是用prototype原型來使用)

3.login.vue中:設定後端的接口位址

前後端分離解決跨域問題:springboot做後端+vue做前端前端部分:後端部分:

 Login.vue

<template>
  <div>
    <div>
      <label>郵箱:<input type="text" v-model="email" placeholder="請輸入你的郵箱"></label>
    </div>
    <div>
      <label>密碼:<input type="password" v-model="password" placeholder="請輸入你的密碼"></label>
    </div>
    <div>
      <p>{{tip}}</p>
      <a href="#" target="_blank" rel="external nofollow"  id="forget">忘記密碼?</a>
    </div>
    <div>
      <button @click="login">登入</button>
      <button @click="register">注冊</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "login",
  data() {
    return {
      email: "",
      password: "",
      tip: ""
    }
  },
  methods: {
    login: function () {
      let data = new FormData();
      data.append('email',this.email);
      data.append('password',this.password);
      this.$axios.post("http://localhost:9527/user/login", data).then(function (response) {
        console.log(response.data);
      }).catch(function (error) {
        console.log(error);
      })
    },

    register: function () {
      let data = new FormData();
      data.append('email',this.email);
      data.append('password',this.password);
      this.$axios.post("http://localhost:9527/user/register", data).then(function (response) {
        console.log(response.data);
      }).catch(function (error) {
        console.log(error);
      })
    }
  }

}
</script>

<style scoped>

</style>
           

4.在index.js裡面添加路由

import Login from '@/components/Login'
           
routes:{
      path: '/login',
      name: Login,
      component: Login
    }
           

後端部分:

在控制器類裡面設定,前端的位址:

@CrossOrigin(origins = "http://localhost:8080", maxAge = 3600)
           
前後端分離解決跨域問題:springboot做後端+vue做前端前端部分:後端部分:

就完成了。

不可思議。

也許還有很多其他辦法。等以後遇到了再總結。

參考别人:

https://www.cnblogs.com/xintao/p/10751806.html

Vue安裝Axios及使用
1.安裝:npm install axios --save-dev


2.main.js中導入
  import axios from 'axios'; /* 引入axios進行位址通路*/
  Vue.prototype.$http = axios;
  (注意:不使用use來使用該例,而是用prototype原型來使用)

3.login.vue中:
  import axios from 'axios';

  axios.post("/api/login?", params).then(function(res) {
    var data = res.data;
    // console.log(data);
    let role = data.result.user.role;
    let token = data.result.token;
    localStorage.setItem("currentUser_token", token); //将token存到本地的localStorage中
    // console.log(localStorage);
    if (data.code == 1) {
    alert(data.msg);
    let _username;
    // console.log(localStorage.getItem("currentUser_token"))
    // console.log(userName)
    that.$router.push({path: "/index",query: { name: userName, role: role }});	//跳轉到 index頁面中并傳遞name和role的值

    (在index頁面中接受參數:PS:let userName = this.$route.query.name;let userRole = this.$route.query.role;)

  } else {

    alert(data.msg);
  }
  }).catch(function(err) {
    console.log("LOGIN_" + err);
  });
(注意:若要使用全局路徑通路請求則需要在config中的index.js中配置proxyTable)
舉例:proxyTable: {
    '/api': {
      target: 'IP+端口', //後端接口位址
      changeOrigin: true, //是否允許跨越
      pathRewrite: {
      '^/api': '/api', //重寫,
      }
     }
   },
           

https://www.jb51.net/article/146888.htm

跨域資源共享CORS(Cross-origin Resource Sharing),是W3C的一個标準,允許浏覽器向跨源的伺服器發起XMLHttpRequest請求,克服ajax請求隻能同源使用的限制。關于CORS的詳細解讀,可參考阮一峰大神的部落格:跨域資源共享CORS詳解。本文為通過一個小demo對該部落格中分析内容的一些驗證。

1.springboot+vue項目的建構和啟動

細節不在此贅述,任何簡單的springboot項目就可以,而前端vue項目隻需用axios發ajax請求即可。

我的demo裡填寫使用者名和密碼,然後點選登入按鈕向背景發起登入請求,js代碼如下:

?

1

2

3

4

5

6

7

8

9

methods:{

login:

function

() {

//var userParams = this.$qs.stringify(this.User);

this

.$axios.post(

"http://localhost:8080/login"

,

this

.User).then(res=>{

alert(res.data);

});

}

}

背景控制器部分,對登入請求的處理:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@RequestMapping(value=

"/login"

,method = RequestMethod.POST, produces =

"application/json;charset=UTF-8"

)

@ResponseBody

public String userlogin(@RequestBody JSONObject user) {

System.out.println(

"name: "

+ user.get(

"name"

));

System.out.println(

"password: "

+ user.get(

"password"

));

String name = (String) user.get(

"name"

);

String password = (String) user.get(

"password"

);

if

(name.equals(

"zsz"

) && password.equals(

"888888"

)){       

return

"login success!"

;

}

else

{

return

"login failed"

;

}

}

背景以8080端口啟動,前台以8081啟動,此時無法跨域,浏覽器控制台會報錯:

2.springboot設定CORS

此處主要有兩種方法(但是貌似有其他部落格還有更多種),在springboot中實作都比較簡單(反正springboot好像就是各種省事各種簡單)。

方法1:

?

1

@CrossOrigin

(origins =

"http://localhost:8081"

, maxAge =

3600

)

直接在控制器方法前注解,設定可以跨域的源ip和端口,以及預檢有效期maxAge等參數。

方法2:

編寫配置類,配置全局的CORS設定。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Configuration

public

class

MyCorsConfig {

@Bean

public

WebMvcConfigurer corsConfigurer(){

return

new

WebMvcConfigurerAdapter() {

@Override

public

void

addCorsMappings(CorsRegistry registry) {

// 限制了路徑和域名的通路

registry.addMapping(

"/**"

)

.allowedOrigins(ALL)

.allowedMethods(ALL)

.allowedHeaders(ALL)

.allowCredentials(

true

);

}

};

}      

}

如果路徑配置成以上的 /**則對所有源路徑均接受跨域通路,當然也可以配置更詳細的路徑。

這樣可以成功通路背景,浏覽器中可以看到http請求和響應的結果如下圖:

3.CORS非簡單請求預檢請求的抓包驗證

根據阮一峰大神的部落格所述,CORS簡單請求隻發送一次請求,伺服器設定支援CORS則會在響應内容中添加Acess-Control-Allow-Origin等字段,否則不添加,浏覽器知道出錯,進而抛出異常;CORS非簡單請求時,會先進行一次預檢(preflight)請求,浏覽器根據響應内容進行正式的XMLHttpRequest請求。

在我的demo中,我通過将http請求的 content-type 設定為application/json進行非簡單請求。此處要說明一下,axios預設情況下發送請求的格式是application/json而不是我之前用jQuery發送ajax請求的application/x-www-form-urlencoded, 而我之前用的另一種方法構造查詢字元串,最終發送請求的content-type會變為application/x-www-form-urlencoded。

?

1

var userParams =

this

.$qs.stringify(

this

.User)

前台請求代碼如本文第一節中所示,在axios請求中直接傳入User對象即可。在後端不設定CORS的時候,控制器資訊為:

協定内容為:

而設定了CORS,預檢請求結果為:

請求成功,并且在響應頭中添加了各種字段。

再次發起XHR請求後,結果為:

以上實驗驗證證明了兩種CORS請求的過程正如預期。

繼續閱讀