自学内容网 自学内容网

Vue3集成搜索引擎智能提示API

需求:

如何在项目中实现像百度搜索框一样的智能提示效果,如下图所示:
在这里插入图片描述

相关知识:

下面是各厂商提供的免费API

厂商请求
百度http://suggestion.baidu.com/su?wd=中国&cb=window.baidu.sug
必应http://api.bing.com/qsonhs.aspx?type=cb&q=#content#&cb=window.bing.sug
谷歌http://suggestqueries.google.com/complete/search?client=youtube&q=#content#&jsonp=window.google.ac.h
好搜https://sug.so.360.cn/suggest?encodein=utf-8&encodeout=utf-8&format=json&word=#content#&callback=window.so.sug
淘宝https://suggest.taobao.com/sug?code=utf-8&q=#content#&callback=window.taobao.sug

以下是百度链接的结果,除了谷歌是下载一个txt文件外,其他厂商基本上都差不多,略有区别。

window.baidu.sug({q:“中国”,p:false,s:[“中国地图”,“中国移动”,“中国消防”,“中国教育考试网”,“中国知网”,“中国人事考试网”,“中国执行信息公开网个人查询”,“中国农业银行”,“中国银行”,“中国高等教育学生信息网(学信网)”]});

说明:window.baidu.sug是百度搜索的一个接口,用于获取搜索建议。通过发送请求,可以获取与输入关键词相关的搜索建议列表。其中,参数q表示搜索关键词,p表示搜索位置,bs表示输入框中的内容,csor表示是否开启拼音纠错,status表示请求状态,s表示搜索建议列表。

请求方式

  1. XMLHttpRequest(XHR)

    • 介绍:XMLHttpRequest是前端最早使用的数据请求方式,它支持异步请求,可以通过设置回调函数处理请求完成后的数据。
    • 特点:虽然在现代浏览器中表现良好,但随着浏览器性能的提升,其性能瓶颈逐渐凸显。此外,XMLHttpRequest的语法相对复杂,使用起来不够直观。
    • 使用场景:适用于一些老旧项目或者需要与多种后端系统交互的场景。
  2. Fetch API

    • 介绍:Fetch是一个现代的、基于Promise的HTTP客户端,用于浏览器和Node.js。它提供了一种更简洁、更易于理解的方式来处理网络请求。
    • 特点:Fetch API的语法简洁、易读,且返回Promises,使得异步操作更加易于管理和链式调用。此外,Fetch API还支持跨域请求和流式响应。
    • 使用场景:适用于现代浏览器中的网络请求处理。
  3. Axios

    • 介绍:Axios是一个基于Promise的HTTP客户端,用于浏览器和Node.js。它扩展了Fetch API,提供了更丰富的功能。
    • 特点:Axios支持请求和响应拦截器、自动转换JSON数据、取消请求等功能。此外,它还提供了统一的错误处理机制。
    • 使用场景:适用于需要处理复杂网络请求的场景,如添加请求和响应拦截器、自动处理JSON数据等。
  4. 表单提交

    • 介绍:通过HTML表单提交数据到服务器。
    • 特点:表单提交是同步请求,会刷新页面。但可以通过设置表单的method属性为POST来避免在URL中暴露数据。
    • 使用场景:适用于简单的数据提交场景。
  5. JSONP

    • 介绍:一种通过<script>标签的src属性跨域请求数据的方式。
    • 特点:JSONP只能发送GET请求,且存在安全风险(如XSS攻击)。
    • 使用场景:适用于解决跨域问题,但现代浏览器更推荐使用CORS(跨源资源共享)来解决跨域问题。

实现:

第一步:Element 提供了 el-autocomplete 组件 el-autocomplete

第二步:发送请求,使用的是 axios ,通过 fetch 组件发送,发现请求成功了,但是无法接受返回的数据

问题:因为API返回的是JSONP数据,JSONP是跨域访问的一种方式,网上很多都是用的原生的 js 代码去发送请求,嵌入到vue中不太方便,因此我想着vue能不能直接发送jsonp 请求,后面发现vue-resource可以发送,但是Vue3项目当前无法继续使用vue-resource进行http请求。

什么是JSONP接口:浏览器端通过

  • JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象
  • JSONP 仅支持 GET 请求,不支持POST、PUT、DELETE 等请求

如果项目中已经配置了 CORS跨域资源共享,为了防止冲突,必须在配置 CORS 中间件之前声明 JSONP 的接口。否则 JSONP 接口会被处理成开启了 CORS 的接口,对于 JSONP,你应该使用 XMLHttpRequest 或者动态创建一个

解决:暂时直接通过后端去调用,响应速度还可以,后面前端调用好了,再来更新此文。

// 核心代码如下,包括发送请求和解析百度接口的数据
String re = HttpRequest.get(url).execute().onSuccess(ResponseSpec::asString);

String regex = "s:\\[(\"(.*?)\"(?:,\\\"(.*?)\\\")*)\\]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(re);

        if (matcher.find()) {
            // 提取匹配到的内容,但这里需要额外的处理,因为正则表达式无法直接处理嵌套的引号
            // 我们可以尝试通过分割逗号来获取每个元素,但需要注意处理可能的转义字符(在这个特定例子中,我们假设没有转义字符)
            String arrayString = matcher.group(1);
            // 移除首尾的多余字符(如果有的话)
            arrayString = arrayString.trim().replaceAll("^\"|\"$", ""); // 移除首尾的双引号(如果有的话)
            // 分割字符串获取每个元素
            String[] elements = arrayString.split("\",\""); // 分割逗号,但注意这里假设没有逗号在引号内

            // 将元素装入列表
            List<String> sList = new ArrayList<>();
            for (String element : elements) {
                // 可能需要额外的处理来移除任何额外的引号或空格
                sList.add(element.trim().replaceAll("^\"|\"$", "")); // 移除首尾的双引号(如果有的话)
            }

            // 将sList封装为List<Object>返回即可,Object中包含value属性
            ......
        } else {
            log.error("未找到匹配的 s 数组内容。");
        }

前端通过XMLHttpRequest,仅供参考

function querySearch(queryString, cb) {
  // 创建一个唯一的回调函数名,以避免命名冲突
  const callbackName = `baiduSugCallback_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

  // 在全局作用域中定义回调函数
  window[callbackName] = function(data) {
    // 调用传入的回调函数,并传入解析后的数据
    cb(data);
    // 清理全局回调函数
    delete window[callbackName];
  };

  // 创建并配置一个 JSONP 请求
  const xhr = new XMLHttpRequest();
  const url = `https://suggestion.baidu.com/su?wd=${encodeURIComponent(queryString)}&cb=${callbackName}`;
  xhr.open('GET', url, true);
  xhr.send();

  // 处理请求失败的情况(可选)
  xhr.onerror = function() {
    // 可以在这里处理错误,例如调用 cb 函数并传入一个错误对象
    delete window[callbackName]; // 确保在出错时也清理回调函数
    cb(new Error('JSONP request failed'));
  };
}

// 使用 querySearch 函数
querySearch('美国', function(data) {
  console.log(data); // 输出解析后的数据
});

原文地址:https://blog.csdn.net/qq_42535394/article/details/143759404

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!