面试会问的 history路由跟反向代理解决跨域的问题

    技术2026-01-24  16

    history模式路由是怎么实现的吗

    history模式路由利用history.pushState改变URL,但并不会刷新页面的原理; 并在改变URL同时切换组件 的显示/隐藏。

    history模式:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div id="div"> <a href="/home">home</a> <a href="/about">about</a> <a href="/other">other</a> </div> <!-- 切换路由,显示不同内容 --> <div class="route"></div> <script> const aEles = document.querySelectorAll('#div>a') const route = document.querySelector('.route') aEles.forEach(item => { item.onclick = function (e) { e.preventDefault() // 切换不同path,显示不同组件(内容) route.innerHTML = map.get(item.getAttribute('href')) // 改变URL,但并不会发请求到浏览器 //参数1,状态对象,相当于是路由的param,附加信息。 //参数2,可以忽略 //参数3 新的URL history.pushState( { id: route.innerHTML }, '', item.getAttribute('href') ) } }) const map = new Map([ ['/home', '我是home'], ['/about', '我是about'], ['/other', '我是other'] ]) //浏览器前进后退的支持, // history.back()、history.forward()、history.go() window.onpopstate = function (ev) { console.log(ev) route.innerHTML = ev.state.id } </script> </body> </html>

    hash模式:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div> <a href="#/home">home</a> <a href="#/about">about</a> <a href="#/other">other</a> <div id="route"></div> </div> </body> <script> const route = document.querySelector("#route") window.onhashchange = function () { const map = new Map([ ["#/home", "我是home"], ["#/about", "我是about"], ["#/other", "我是other"], ]) route.innerHTML = map.get(location.hash) } </script> </html>

    2.反向代理解决跨域的问题

    var http = require('http') http.createServer(function (request, response) { // 设置允许跨域的域名,*代表允许任意域名跨域 response.setHeader('Access-Control-Allow-Origin', '*') //允许的header类型 response.setHeader('Access-Control-Allow-Headers', 'Content-type') //跨域允许的请求方式 response.setHeader( 'Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS,PATCH' ) //可选,用来指定本次预检请求的有效期,单位为秒。在此期间,不用发出另一条预检请求。 response.writeHead(200, { 'Content-Type': 'application/json' }) // 代理请求目标服务器的数据 getTargetServerData().then(data => { // 发送响应数据 "Hello World" response.end(data) }) }).listen(8888) // 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/') // 代理请求目标服务器的数据 function getTargetServerData () { var options = { host: '129.211.82.55', port: 3000, path: '/api/home/swipers', method: 'GET' } var body = '' return new Promise((resolve, reject) => { var req = http.request(options, function (res) { res.on('data', function (data) { body += data }).on('end', function () { resolve(body) }) }).on('error', function (e) { reject(e) }) req.end() }) }

    如何配置webpack的代理

    一般前端项目启动在localhost:8080, 联调需要访问不同环境的服务器,如果服务器恰好没有设置CORS,那么就会跨域。反向代理可以解决跨域问题,前端访问代理服务器,代理服务访问目标服务器,由于服务器访问服务器是不是跨域的,所以前端也就可以正常获取了请求数据。最常见的反向代理服务器就是Webpack Server, 配置webpack代理,匹配成功的请求的URL,webpack代理服务器访问target服务器,返回请求

    proxy: { // 请求/api/home/swipers时,实际上是在请求http://129.211.82.55:3000/api/home/swipers '/api': { target: 'http://129.211.82.55:3000' } }

    Processed: 0.014, SQL: 10