V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
GeekHub
black11black
V2EX  ›  问与答

Websocket 有办法渲染 html 页面吗?

  •  
  •   black11black · 55 天前 · 1539 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,目前有一个计算型后端任务,假定就是递归计算斐波那契数列吧,

    单个计算任务大概需要几分钟左右,计算出结果后会返回一个由后端渲染的 html 页面。

    我希望在计算过程当中可以让用户实时获取到渲染进度,这点通过 websocket 通信可以很简单实现。

    但是问题在于最终返回结果不是 json 数据而已 html 页面。有什么解决方案能实现完成后跳转吗?自己粗略想了几个方法都感觉比较脏,谢谢大家

    21 条回复    2020-08-08 09:57:52 +08:00
    xw900812
        1
    xw900812   55 天前
    应该是可以实现的。。。。GitHub Pull Request 就是通过 WS 即时渲染页面来告诉用户的。
    yyfearth
        2
    yyfearth   55 天前
    当然可以 websocket 就像 http 一样 只是一种协议 你可以用来传输任何内容
    不管是 json html 还是 zip exe 都可以

    关键是你前端如何实现
    对于你的这种需求 渲染进度 传输 json 或者 数字 string 会明显更加简单 相比传输整个 html
    你只需要把进度传给前端的进度条组建就可以了

    除非你完全不会前端 JS 只会用后端渲染整个页面 html
    那么你可以简单的用 JS 把整个页面替换掉即可 但是这样比较笨拙
    而且你要用的 websocket 你一定要有前端 JS
    既然已经需要用到前端 JS 那么传输 json 来修改进度条要简单的多
    nvkou
        3
    nvkou   55 天前 via Android
    所以 ws 一直在发送进度?发送完之后再发送一个 html ?这个实现没啥问题,问题在前端要区分这 2 种消息。其实如果前端都能知道资源( HTML )就绪了,直接重定向到资源不就是了吗
    muzuiget
        4
    muzuiget   54 天前
    前端写点 js,某个 div 直接设 innerHTML 就完了。

    那么问题来了,为何 websocket 结果要直接返回完整页面 html,返回部分 html 片段再在前端按需拼凑不好吗?
    Orenoid
        5
    Orenoid   54 天前
    与 websocket 无关吧,你的问题应该是怎么用 JS 将一段 HTML 文本渲染到浏览器中。
    sugars
        6
    sugars   54 天前
    iframe 可行吗?
    iConnect
        7
    iConnect   54 天前 via Android
    前端你首先要会建立 websocket 连接,才能接收服务器数据。

    这个搞定了,后端返回个进度百分百数据,前端直接显示在页面上,啥都不用做都行。
    Exin
        8
    Exin   54 天前
    ```js
    websocket.on('data', event => {
    targetElement.innerHTML = event.data // if data is HTML text
    })
    ```
    Exin
        9
    Exin   54 天前
    直接扔给 DOM 渲染是最符合楼主描述的设计的,不然就不应该通过 ws 传递 HTML
    rrfeng
        10
    rrfeng   54 天前
    前几天还有个人在本站发自己的作品,全程只有一个 websocket 把页面搞起来(忘记叫啥了
    whypool
        11
    whypool   54 天前
    ajax 轮询就行要啥 ws
    lower
        12
    lower   54 天前
    赞同 9 楼,就算是跳转,新页面加载 html 不也是 dom 新渲染页面么
    black11black
        13
    black11black   54 天前
    @Orenoid 就是这个问题,如果不行的话还有没有其他方法实现。如果要实现针对单个请求服务端开辟出来一个单独的状态网址,我感觉就太脏了
    black11black
        14
    black11black   54 天前
    @Exin 感谢,似乎寻求的就是这种实现方式。请问这种 html 传递有什么特殊规则吗,比如某些字符串或者某些命令不能用,还是说只要普通的 html 能渲染出的页面丢到里面都能跑(配合有效 js 和 css 的情况下)
    Exin
        15
    Exin   54 天前
    @black11black
    没什么特殊规则
    普通的 HTML 都能跑,不过不适合用完整的 HTML 文件(根元素是 html 标签),最好是部分区块(比如某个 div 元素下的内容)
    如果每次新插入内容的会覆盖掉之前的,那 css 应该不会有问题,js 要注意副作用带来的问题(即修改全局变量、设置定时器)
    kuro1
        16
    kuro1   54 天前
    可以 ws 进度完成以后发起一次 post 请求,跳转就行了
    black11black
        17
    black11black   54 天前
    @Exin 我实现的时候发现有一个问题,后端页面有 js 动态渲染的内容,比如后端返回的 html 中包含有<script>console.log("hello world")</script>这类的标签。单纯 html 的部分倒是顺利嵌入进去了没什么复杂的。js 的部分有办法实现动态加载吗?我 js 不是很熟
    Exin
        18
    Exin   53 天前
    那可能“用 ws 传递 HTML 并渲染”的不太合理,考虑下把 ws 改为普通 HTTP API 然后用 iframe 显示?
    black11black
        19
    black11black   53 天前
    @Exin 感谢回复,主要需求在于展示渲染进度,倒并不是用 ws,但是其他实现方式的话,比如 ajax 轮询,以我粗浅的理解就需要后端生成临时网址来单独处理这一次会话事务,引起的权限和有效期等等问题实现起来并不简单。不知道这种需求普遍做法是怎么样的
    Exin
        20
    Exin   51 天前
    "普通 HTTP API"不一定用于 AJAX,AJAX 指的是 JS 触发的网络请求,使用 iframe 触发就不是 AJAX 了

    可能没有你理解的那么复杂。我认为可以使用单个网址,比如 `/view/status` ,鉴权和你目前的 ws 方式可以一致,按需设置缓存,父页面通过 iframe 显示这一网址,并用 JS 定时控制 iframe 刷新
    black11black
        21
    black11black   46 天前
    @Exin 感谢,似乎确实可行,想多了
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1346 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 23:17 · PVG 07:17 · LAX 16:17 · JFK 19:17
    ♥ Do have faith in what you're doing.