服务端和客户端下拉框幂等如何实现

100 阅读3分钟

以下是实现下拉框数据请求幂等性的一些方法,以获取省市区数据为例:

一、服务器端实现幂等性的思路

1. 使用唯一标识符和缓存机制

  • 当客户端首次请求省市区数据时,服务器会生成一个唯一标识符(如 UUID)并将其与相应的数据结果存储在缓存中。

  • 后续的请求,如果包含相同的唯一标识符,服务器将直接从缓存中返回数据,而不是重新生成或查询。

收起

python

import uuid
from flask import Flask, jsonify, request
from flask_caching import Cache

app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE':'simple'})

@app.route('/get_regions', methods=['GET'])
def get_regions():
    # 从请求参数中获取唯一标识符
    request_id = request.args.get('request_id')
    if request_id:
        # 尝试从缓存中获取数据
        cached_data = cache.get(request_id)
        if cached_data:
            return jsonify(cached_data)
    # 模拟从数据库或其他数据源获取省市区数据
    regions = [
        {"id": 1, "name": "省份1", "cities": [{"id": 11, "name": "城市11", "districts": [{"id": 111, "name": "区县111"}]}]},
        {"id": 2, "name": "省份2", "cities": [{"id": 21, "name": "城市21", "districts": [{"id": 211, "name": "区县211"}]}]},
    ]
    if request_id:
        # 将数据存储在缓存中,并设置一个较长的过期时间,因为这类数据通常不会频繁更新
        cache.set(request_id, regions, timeout=3600)
    return jsonify(regions)


if __name__ == "__main__":
    app.run(debug=True)

代码解释

  • 上述代码使用 Python 的 Flask 框架和 Flask-Caching 扩展实现了一个简单的服务器端幂等请求处理。

  • 首先,服务器检查请求中是否包含 request_id 参数。

  • 如果 request_id 存在且对应的数据在缓存中,直接返回缓存数据。

  • 若不在缓存中,会模拟从数据库或其他数据源获取省市区数据,存储到缓存中并设置过期时间,最后返回数据。

二、客户端实现幂等性的思路

1. 存储请求结果

  • 客户端在第一次请求获取省市区数据成功后,将结果存储在本地存储(如浏览器的 localStorage 或 Vue 中的 Vuex 等)。

  • 后续的请求,先检查本地存储是否有数据,如果有则使用本地数据,避免再次请求服务器。

以下是一个使用 Vue 和 Vuex 的简单示例:

Vue 组件部分

收起

vue

<template>
  <select v-model="selectedProvince">
    <option v-for="province in provinces" :key="province.id" :value="province.id">{{ province.name }}</option>
  </select>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  name: 'RegionSelect',
  computed: {
 ...mapState(['provinces'])
  },
  methods: {
 ...mapActions(['fetchProvinces'])
  },
  created() {
    if (!this.provinces.length) {
      this.fetchProvinces();
    }
  }
};
</script>

Vuex 部分

收起

javascript

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    provinces: []
  },
  mutations: {
    setProvinces(state, provinces) {
      state.provinces = provinces;
    }
  },
  actions: {
    fetchProvinces({ commit }) {
      // 先检查本地存储
      const storedProvinces = localStorage.getItem('provinces');
      if (storedProvinces) {
        commit('setProvinces', JSON.parse(storedProvinces));
      } else {
        axios.get('/get_regions')
       .then(response => {
            const provinces = response.data;
            // 存储到本地存储
            localStorage.setItem('provinces', JSON.stringify(provinces));
            commit('setProvinces', provinces);
          })
       .catch(error => {
            console.error(error);
          });
      }
    }
  }
});

代码解释

  • 在 Vue 组件中,使用 v-for 生成下拉框的选项,数据来自 Vuex 的 provinces 状态。

  • 在 Vuex 的 fetchProvinces 动作中,首先检查本地存储是否有 provinces 数据。

  • 如果有,直接将其提交到状态;如果没有,向服务器请求数据,将数据存储在本地存储并提交到状态。

三、两者结合的方式

  • 服务器端确保数据的缓存和请求的一致性,客户端确保减少不必要的请求。这样,即使网络状况不佳,客户端重复发送请求,服务器也可以根据唯一标识符提供一致的数据,同时客户端也能快速使用本地存储的数据,减少对服务器的依赖。

四、使用场景和优化

  • 这种实现方式适用于省市区数据相对稳定,不会频繁更新的情况。如果数据可能更新,可以为缓存设置合理的过期时间,并在服务器更新数据时清除相应的缓存或通知客户端更新本地存储。

你可以根据自己的开发环境和技术栈选择合适的方法。