MST

星途 面试题库

面试题:Vue跨域请求中如何优化安全性及性能

在Vue应用进行跨域网络请求时,安全性和性能都是至关重要的。请从安全角度,如防止CSRF攻击、XSS攻击等方面,以及性能角度,如请求合并、缓存策略等方面,详细阐述你会采取哪些措施来优化Vue中的跨域网络请求,并说明这些措施的原理和实现方式。
50.5万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

安全角度

  1. 防止CSRF攻击
    • 原理:CSRF(Cross - Site Request Forgery,跨站请求伪造)是攻击者盗用了用户的身份,以用户的名义发送恶意请求。通过在请求中添加一个只有服务器和用户知道的token,服务器验证token的合法性来防止CSRF攻击。
    • 实现方式
      • 服务器端:在用户登录时生成一个唯一的CSRF token,并将其存储在用户的session中。例如在Node.js + Express应用中,可以使用csrf中间件,安装npm install csrf,然后在服务器代码中:
const csrf = require('csrf');
const csrfProtection = csrf({ cookie: true });
app.get('/getCsrfToken', csrfProtection, (req, res) => {
    res.json({ csrfToken: req.csrfToken() });
});
  - **客户端(Vue)**:在Vue组件的created钩子函数中,通过axios等HTTP库获取CSRF token,并存储在Vuex或组件data中。例如:
import axios from 'axios';
export default {
    data() {
        return {
            csrfToken: ''
        };
    },
    created() {
        axios.get('/getCsrfToken')
          .then(response => {
                this.csrfToken = response.data.csrfToken;
            });
    },
    methods: {
        submitForm() {
            axios.post('/protectedRoute', { data: this.formData }, {
                headers: {
                    'X - CSRF - Token': this.csrfToken
                }
            });
        }
    }
};
  1. 防止XSS攻击
    • 原理:XSS(Cross - Site Scripting,跨站脚本攻击)是攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。通过对用户输入进行过滤和转义,以及对输出进行严格的HTML编码来防止XSS攻击。
    • 实现方式
      • 过滤输入:使用正则表达式或第三方库(如DOMPurify)对用户输入进行过滤。例如在Vue组件的methods中:
import DOMPurify from 'dompurify';
export default {
    methods: {
        sanitizeInput(input) {
            return DOMPurify.sanitize(input);
        }
    }
};
  - **编码输出**:在Vue模板中,Vue默认会对数据进行HTML编码,确保特殊字符被转义。例如:
<template>
    <div>{{ userInput }}</div>
</template>
<script>
export default {
    data() {
        return {
            userInput: '<script>alert("XSS")</script>'
        };
    }
};
</script>

这里userInput会被编码后显示,而不会作为脚本执行。

性能角度

  1. 请求合并
    • 原理:将多个相似或相关的请求合并为一个请求,减少网络请求次数,从而降低网络开销,提高性能。
    • 实现方式
      • 使用队列:可以创建一个请求队列,当有新的请求时,判断队列中是否有相同类型或相关的请求。如果有,则将新请求的数据合并到已有请求中;如果没有,则将新请求加入队列。例如:
const requestQueue = [];
function sendRequest() {
    if (requestQueue.length === 0) return;
    const mergedData = requestQueue.reduce((acc, req) => {
        // 假设请求数据是对象,这里简单合并
        return { ...acc, ...req.data };
    }, {});
    axios.post('/batchRequest', mergedData)
      .then(response => {
            // 处理响应
            requestQueue.length = 0;
        });
}
export function queueRequest(data) {
    requestQueue.push({ data });
    if (requestQueue.length === 1) {
        setTimeout(sendRequest, 100); // 延迟一段时间发送,等待更多请求加入
    }
}
  1. 缓存策略
    • 原理:对于一些不经常变化的数据,将请求结果进行缓存,当再次请求相同数据时,直接从缓存中获取,减少服务器负载和网络请求时间。
    • 实现方式
      • 使用内存缓存:在Vue组件或Vuex中使用一个对象来存储缓存数据。例如在Vuex的actions中:
const state = {
    cache: {}
};
const actions = {
    async getCachedData({ state, commit }, key) {
        if (state.cache[key]) {
            return state.cache[key];
        }
        const response = await axios.get('/data');
        commit('SET_CACHE', { key, value: response.data });
        return response.data;
    }
};
const mutations = {
    SET_CACHE(state, { key, value }) {
        state.cache[key] = value;
    }
};
export default {
    state,
    actions,
    mutations
};
  - **使用浏览器本地缓存**:可以使用`localStorage`或`sessionStorage`来存储缓存数据。例如:
export async function getCachedData(key) {
    const cached = localStorage.getItem(key);
    if (cached) {
        return JSON.parse(cached);
    }
    const response = await axios.get('/data');
    localStorage.setItem(key, JSON.stringify(response.data));
    return response.data;
}