SpringBoot實現Vue-Admin-Template跨域訪問資源


SpringBoot+Vue-admin-template 實現跨域數據查詢

前言

本文的案例是基於Vue-admin-template項目改造的簡化版Vue后台管理模板案例

在前兩篇的實案例之上,記錄一下實現登錄、退出、查詢數據、以及跨域訪問資源

的一些細節,方便自己日后忘了快速撿起,同時也是對之前兩篇vue實踐文章總結

技術棧

技術棧還是沿用SpringBoot+Vue-admin-template 實現增刪改查中技術,版本也一致

案例演示

案例實踐

1.完全按照前端的定義好的請求格式實現登錄和退出接口

1.1 保持根目錄下.env.development的基礎API路徑不變

# base api
VUE_APP_BASE_API = '/dev-api'

1.2 設置根目錄下vue.config.js的代理到后端服務8080端口

 devServer: {
    port: port,
    open: false,
    overlay: {
      warnings: false,
      errors: true
    },
    // before: require('./mock/mock-server.js') 注釋mock-server生成的模擬數據
    proxy: {
      '/dev-api': {	
        target: `http://localhost:8080`, // 后台服務地址
        changeOrigin: true,
        pathRewrite: {
          '^/dev-api': '/dev-api' // 路徑重寫
        }
      }
    }
  },

1.3 保持src\api\user.js的登錄、獲取用戶信息、退出的接口不變

export function login(data) {
  return request({
    url: '/vue-admin-template/user/login',
    method: 'post',
    data
  })
}

export function getInfo(token) {
  return request({
    url: '/vue-admin-template/user/info',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/vue-admin-template/user/logout',
    method: 'post'
  })
}

2.前端mock模擬生成的數據細節

2.1 login登錄接口和info接口詳細的數據封裝

// 定義tokens對象存放token 在對象中模擬admin和editor兩個角色的token 
const tokens = {
  admin: {
    token: 'admin-token'
  },
  editor: {
    token: 'editor-token'
  }
}
// 分別以admin和editor兩個角色的token值作為key,然后返回的數據封裝成一個整體對象存放進value
const users = {
  'admin-token': {
    roles: ['admin'],
    introduction: 'I am a super administrator',
    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
    name: 'Super Admin'
  },
  'editor-token': {
    roles: ['editor'],
    introduction: 'I am an editor',
    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
    name: 'Normal Editor'
  }
}
// 模塊化導出登錄接口(可以理解為向外暴露,方便JS識別)
export default [
  // user login
  {
    url: '/vue-admin-template/user/login',
    type: 'post',
     // ES6箭頭函數
    response: config => {
      const { username } = config.body // 從body中取出username
      const token = tokens[username]	//根據username在tokens中獲取對應token

      // mock error 當不是admin或者editor賬號登錄時,就會獲取不到token報錯 產生mock error
      if (!token) {
        return {
          code: 60204,
          message: 'Account and password are incorrect.'
        }
      }
		// 成功就會返回code為20000,data是返回數據的key值,token是一個value值的對象
      return {
        code: 20000,
        data: token
      }
    }
  },
     // get user info  獲取用戶信息
  {
    url: '/vue-admin-template/user/info\.*',
    type: 'get',
    response: config => {
      const { token } = config.query // 從config中取出token
      const info = users[token]		// 根據token從用戶中取出對應用戶信息

      // mock error
      if (!info) {
        return {
          code: 50008,
          message: 'Login failed, unable to get user details.'
        }
      }

      return {
        code: 20000,
        data: info	// 返回用戶信息
      }
    }
  },

  // user logout 用戶退出
  {
    url: '/vue-admin-template/user/logout',
    type: 'post',
    response: _ => {
      return {		// 無請求內容直接返回 success和20000
        code: 20000,
        data: 'success'
      }
    }
  }
]

2.2 login登錄接口返回的數據格式具體表現形式

{
    "code": 20000,
    "data": {
        "token": "admin-token"
    }
}

2.3 info接口返回的數據格式具體表現形式

{
    "code":20000,
    "data":{
        "roles":["admin"],
        "introduction":"I am a super administrator",
        "avatar":"https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
        "name":"Super Admin"
	}
}

2.4 logout接口返回的數據格式具體表現形式

{
    "code":20000,
    "data":"success"
}

3.用SpringBoot編寫與mock.js同樣的數據返回

3.1 User.java實體類

@Data
public class User {
    private List<String> roles;
    private String introduction;
    private String avatar;
    private String name;
    private String username;
    private String password;
}

3.2 LoginController.java控制器類

@Controller
public class LoginController {
    @CrossOrigin
    @PostMapping(value = "/vue-admin-template/user/login")
    @ResponseBody
    public Map login(@RequestBody User user) {
        String username = user.getUsername();
        HashMap<String, Object> tokens = new HashMap<>();

        tokens.put("admin","admin-token");
        tokens.put("editor","editor-token");

        HashMap<String, Object> response = new HashMap<>();
        HashMap<String, Object> responseData = new HashMap<>();
        responseData.put("token",tokens.get(username));
        response.put("code",20000);
        response.put("msg","登錄成功");
        response.put("data",responseData);
        return response;
    }

    @CrossOrigin
    @GetMapping(value = "/vue-admin-template/user/info")
    @ResponseBody
    public Map info(@RequestParam("token")String token) {

        HashMap<String, Object> users = new HashMap<>();

        User adminUser = new User();
        User editorUser = new User();

       
        List<String> adminRole = new ArrayList<String>();
        adminRole.add("admin-token");  
        List<String> editorRole = new ArrayList<String>();
        adminRole.add("editor-token");

        adminUser.setRoles(adminRole);
        adminUser.setIntroduction("I am a super administrator");
        adminUser.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        adminUser.setName("Super Admin");
        
        editorUser.setRoles(editorRole);
        editorUser.setIntroduction("I am an editor");
        editorUser.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        editorUser.setName("Normal Editor");

        users.put("admin-token",adminUser);
        users.put("editor-token",editorUser);

        HashMap<String, Object> responseData = new HashMap<>();
        responseData.put("code",20000);
        responseData.put("msg","登錄成功");
        responseData.put("data",users.get(token));

        return responseData;
    }
    
    @CrossOrigin
    @PostMapping(value = "/vue-admin-template/user/logout")
    @ResponseBody
    public Map logout() {
        HashMap<String, Object> responseData = new HashMap<>();
        responseData.put("code",20000);
        responseData.put("msg","退出成功");
        responseData.put("data","success");
        return responseData;
    }
}

4.同源策略以及跨域訪問資源

4.1同源策略

同源策略是一種保證瀏覽器網絡較為安全的策略模式和功能,同源策略最早出現在網景公司旗下的網景瀏覽器上

什么是同源

源:由協議,域名,端口三者組成,

同源:指協議,域名,端口這三者相同

同源策略: 瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源

舉個例子:

http://localhost:9528下的腳本在沒有明確授權的情況下,是不能讀寫http://localhost:8080下的資源

什么是跨域

瀏覽器在遵守同源策略模式下,不是同源的腳本不能操作其他源下面的對象。

想要操作另一個源下的對象是就需要跨域。

舉例:

http://localhost:9528下的腳本想要訪問http://localhost:8080下的JSON數據或者CSS,IMAGES等靜態資源,需要進行跨域操作,這種操作稱為跨域訪問資源(跨域讀和寫資源)

4.2跨域解決方案(跨域的實現方式)

1.JSONP方式

首先必須要知道的是帶有"src"這個屬性的標簽都擁有跨域的能力,比如


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM