Fork me on GitHub

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

单页面应用hash、history原理以及JSONP的分析

单页面应用核心:不通过后端完成路由切换
(Vue、React路由切换原理类似)

history模式基于window.history/history(this===window,不写window直接可以访问),原本只有back()、go()、forward()API,在HTML5中新增pushStatereplaceState({new State},titlexxx,url)(这里的state可以在history中拿到,类似传参)

优点:
  • 即使相同的url也会被推进浏览历史栈中
  • state可以传obj类型数据作为参数,而hash只能传#短字符串
  • 还有个title可以等待使用
缺点
  • 需要后端配置支持,每一种路由需要后端有相应的接收处理,不能仅仅是最外层的url
    • 一般是通配符+返回主页面文件(此做法原因:每一次都返回打包好的index.html文件,由前端去根据state参数具体展示)
      没次go、bach、replace会触发popState方法`

hash模式基于location.href+location.hash完成,由#开头的字符串组成区分不同的hash字符串

优点
  • #及以后的值不会传给后端,而history会
  • 由上可知,hash模式不需要左后端配置
缺点
  • 不美观
    home.html文件
<body>
    <div>
        <button id='btn1'>按钮1</button>
        <button id="btn2">按钮2</button>
    </div>
</body>
<script>
    const bindEventListener = function (type) {
        const historyEvent = history[type];
        return function () {
            const newEvent = historyEvent.apply(this, arguments);
            const e = new Event(type);
            e.arguments = arguments;
            window.dispatchEvent(e);
            return newEvent;
        };
    };
    history.pushState = bindEventListener('pushState');
    history.replaceState = bindEventListener('replaceState');
    window.addEventListener('replaceState', function (e) {
        console.log('THEY DID IT AGAIN! replaceState');
    });
    window.addEventListener('pushState', function (e) {
        console.log('THEY DID IT AGAIN! pushState');
    });

    document.addEventListener('popstate', (e) => {
        console.log(e, 'popstate');
    })
    document.addEventListener('hashchange', (e) => {
        console.log(e, 'hashchange');
    })
    let btn1 = document.getElementById('btn1')
    let btn2 = document.getElementById('btn2')
    btn1.addEventListener('click', (e) => {
    })
</script>

index.html文件

<body>
    <div id='root'>
        测试
    </div>
</body>
<script>
    function callBack(data){
        var box = document.createElement('div')
        box.innerText = '回来了'
        root.appendChild(box)
    }
    function genScript(url){
        var newS = document.createElement('script');
        newS.src = url
        window.onload = function(){
            root.appendChild(newS)
        }
    }
</script>
<script>
    var root = document.getElementById('root')
    genScript('http://localhost:8080/test?cb=callback')
</script>

app.js文件

const http = require('http')
const fs = require('fs')
const httpPort = 8080

http.createServer((req, res) => {
  fs.readFile('home.html', 'utf-8', (err, content) => {
    console.log(req.url);
    if (err) {
      console.log('We cannot open "index.html" file.')
    }
    console.log('接收到');
    res.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8'
    })

    res.end()
  })
}).listen(httpPort, () => {
  console.log('Server listening on: http://localhost:%s', httpPort)
})

https://juejin.cn/post/6844903552519766029

posted @   365/24/60  阅读(142)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示