V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
lolizeppelin
V2EX  ›  JavaScript

浏览器端 js 的 socket 都藏哪去了

  •  1
     
  •   lolizeppelin · 2018-04-15 09:32:49 +08:00 · 8628 次点击
    这是一个创建于 2421 天前的主题,其中的信息可能已经有所发展或是发生改变。

    fetch 不提供 timeout,只能设定时器让函数退出但控制不了实际 socket

    尝试了下搜索找 js 设置 socket timeout 居然是其他模块的

    fecth 底层的 sokcet 是咋弄的?

    虽然见过用过的语言不多...但还真没见过 js 这样不暴露 socket 的.....想 http 请求设置 timeout 就这么难?

    40 条回复    2018-04-16 13:19:01 +08:00
    rookiebulls
        1
    rookiebulls  
       2018-04-15 09:36:29 +08:00 via iPhone   ❤️ 1
    axios 了解一下
    Lxxyx
        2
    Lxxyx  
       2018-04-15 09:37:22 +08:00 via Android
    XHR 有 timeout,fetch 是 promise,目前浏览器还不支持 abort 方法。你可以看 axios 的 cancel Token 实现,我用那个实现过 fetch 的 timeout
    duan602728596
        3
    duan602728596  
       2018-04-15 09:42:58 +08:00 via iPhone
    想用 socket,请使用 html5 的 WebSocket
    lolizeppelin
        4
    lolizeppelin  
    OP
       2018-04-15 09:44:54 +08:00
    @duan602728596
    不是要用 socket,是要通过设置 sockettimeout 实现 http timout
    多么普通的需求 因为 js 没暴露 socket 对象不能操作
    和 websocket 没一毛钱关系
    lolizeppelin
        5
    lolizeppelin  
    OP
       2018-04-15 09:47:43 +08:00
    @Lxxyx
    无论什么 timeout 都要通过 socket 设置...请问 axios 是通过什么方式控制了 socket 的 timeout 的?
    learnshare
        6
    learnshare  
       2018-04-15 10:01:09 +08:00
    lolizeppelin
        7
    lolizeppelin  
    OP
       2018-04-15 10:09:00 +08:00
    @Lxxyx
    稍微看了一下 通过 XMLHttpRequest 的 abort()可以让底层的 socket 强制断开?

    - -abort 是什么鬼 orz

    也是说 js 能直接控制的最底层的方法是 XMLHttpRequest ?
    duan602728596
        8
    duan602728596  
       2018-04-15 10:15:14 +08:00 via iPhone
    @lolizeppelin 如果是 xhr,我记得是可以设置超时时间的。fetch 的话,fetch 可以在发送请求后设置定时器,判断在规定时间内是否有数据返回,不过嵌套的 Promise 很蛋疼
    jin5354
        9
    jin5354  
       2018-04-15 10:26:13 +08:00
    fetch API 没有暴露 timeout,接触不到 socket 没救
    你只能用 Promise.race 曲线实现超时
    lolizeppelin
        10
    lolizeppelin  
    OP
       2018-04-15 10:28:00 +08:00
    @duan602728596
    @learnshare

    这些都只能让自己函数结束没关闭底层连接....我要的是正常的关闭连接.....

    话说设置 http 请求超时时间又不是什么偏门的的需求,fetch 为什么就不实现呢......
    duan602728596
        11
    duan602728596  
       2018-04-15 10:39:42 +08:00   ❤️ 1
    VDimos
        12
    VDimos  
       2018-04-15 10:42:11 +08:00 via Android
    fetch 不行,xmlhttprequest 有个 timeout 属性。这个我需求的确挺偏的
    lolizeppelin
        13
    lolizeppelin  
    OP
       2018-04-15 10:48:31 +08:00
    @duan602728596
    谢谢我试试
    breeswish
        14
    breeswish  
       2018-04-15 11:35:15 +08:00
    浏览器端底层的 socket 是不暴露的,例如你不能使用 http 或 websocket 以外的协议。至于为啥这样做……至少安全性上有这样的要求。
    wwqgtxx
        15
    wwqgtxx  
       2018-04-15 12:41:44 +08:00   ❤️ 2
    要是能那么容易暴露底层 socket 的话,还要 websocket 干嘛,各种类库早就自己跑私有协议了。
    要说为什么,你要是暴露底层 socket 这样就能轻松绕过 cros 规则,浏览器的各种安全规则全都形同虚设了
    codehz
        16
    codehz  
       2018-04-15 12:49:57 +08:00   ❤️ 1
    tommyZZM
        17
    tommyZZM  
       2018-04-15 13:39:43 +08:00
    题主这个需求,跟 socket 不 socket 没什么关系
    tommyZZM
        18
    tommyZZM  
       2018-04-15 13:44:22 +08:00
    ```
    // example
    let someReq = timeout_ms => new Promise((resolve, reject) => {
    let timeout = setTimeout(_ => reject(), timeout_ms);
    fetch(...).then(resolve, reject).then(_ => clearTimeout(timeout));
    });

    // useage
    someReq(1000);
    ```
    BOYPT
        19
    BOYPT  
       2018-04-15 13:52:28 +08:00
    记得 jquery 里面 timeout 的实现是开个定时器,超时没返回就 reject,
    seeker
        20
    seeker  
       2018-04-15 14:03:54 +08:00
    - 不用 socket 也可以达到你的需求
    - 浏览器中的 js 控制不了原生的 socket
    - 平台是浏览器,浏览器实现了 socket 的封装
    azh7138m
        21
    azh7138m  
       2018-04-15 14:15:45 +08:00 via Android
    Promise.race +1
    自己封装一下也不麻烦
    lolizeppelin
        22
    lolizeppelin  
    OP
       2018-04-15 14:51:16 +08:00
    @tommyZZM
    @azh7138m

    axios 基于 xmlhttprequest 可以做到
    fetch 需要 AbortController 支持才能做到,AbortController 需要对浏览器版本要求高

    说 Promise 做得到的你们都是只写 js 的前端吧?只要自己函数能正常就行了,完全不关心底层连接的?
    porrat
        23
    porrat  
       2018-04-15 15:39:33 +08:00 via iPhone   ❤️ 1
    整天底层底层,你咋不自己捡石头刻一个 COU 呢
    porrat
        24
    porrat  
       2018-04-15 15:39:48 +08:00 via iPhone
    打错了,CPU
    qiuyk
        25
    qiuyk  
       2018-04-15 15:59:06 +08:00   ❤️ 1
    GabrielChen
        26
    GabrielChen  
       2018-04-15 16:45:15 +08:00
    这个楼主有点意思
    Yooe
        27
    Yooe  
       2018-04-15 16:45:19 +08:00
    @qiuyk 哈哈哈,也许应该写 C++或 C,才没这些问题吧。。。。
    qiuyk
        28
    qiuyk  
       2018-04-15 16:55:19 +08:00
    @Yooe 哈哈哈哈 其实没别的意思 就是感觉楼主要被逼疯了 觉得有点好玩而言
    lzvezr
        29
    lzvezr  
       2018-04-15 19:45:38 +08:00 via Android
    总感觉楼主应该是个习惯看文档的人,如果是这样的话,文档没提供的就是不支持
    azh7138m
        30
    azh7138m  
       2018-04-15 19:48:58 +08:00 via Android
    @lolizeppelin 我不兼容低于 chrome57 的:)
    azh7138m
        31
    azh7138m  
       2018-04-15 19:52:32 +08:00 via Android
    蛤,看了下β才有这个,我觉得 race 可以,不懂为啥非要这个玩意
    lolizeppelin
        32
    lolizeppelin  
    OP
       2018-04-15 21:44:49 +08:00
    @qiuyk
    js 写起来是有点被逼疯

    @azh7138m
    因为虽然页面里 js 正常运行但是 socket 还一直在工作,而且会完成的本来要做的工作..... Promise race 的做法只是当没看见然后不再理会而已...

    @lzvezr
    因为我实在不明白为什么这么基本的 http 请求超时接口里居然没有让我怀疑自己不会用....
    zzNucker
        33
    zzNucker  
       2018-04-15 23:27:19 +08:00   ❤️ 1
    楼主连 js 都学不明白还有脸说别人是只写 js 的前端,笑死我了
    archliinux
        34
    archliinux  
       2018-04-16 00:51:03 +08:00 via Android   ❤️ 2
    楼主就是以前那个用浏览器跑定时任务的 php 大神..🐶
    wwqgtxx
        35
    wwqgtxx  
       2018-04-16 00:59:49 +08:00
    @archliinux 我就说这 ID 看着眼熟就是想不起来之前在哪里见过
    Sparetire
        36
    Sparetire  
       2018-04-16 04:30:34 +08:00 via Android   ❤️ 1
    不暴露 socket 是浏览器安全策略的要求,浏览器的 http api 本来就是受限的,不要觉得自己会比浏览器厂商来得聪明
    至于 fetch,自己用 xmlhttprequest 封装一下也没差
    浏览器提供了中断请求和超时回调的接口
    https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort
    https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/timeout
    https://developer.mozilla.org/en-US/docs/Web/Events/timeout
    至于 socket 断了没有我也不知道,这取决于浏览器的实现了,真想知道的话,抓个包看看也不是什么难事
    作为学习去了解底层细节无可厚非,但是作为接口的使用者,不需要也不应该去纠结底层的实现,本来就应该面向接口而不是面向具体实现编程,浏览器厂商很好地屏蔽了底层细节反而做得很正确
    Bryan0Z
        37
    Bryan0Z  
       2018-04-16 08:07:50 +08:00 via Android
    @archliinux 没看到记录里有啊
    tommyZZM
        38
    tommyZZM  
       2018-04-16 09:25:11 +08:00
    @lolizeppelin

    问题是你这个功能需求,跟底层不底层没什么关系

    你想要看 fetch 底层,请直接阅读 Chromium 源码。

    另外我想要指出的是,fecth 这个 API 是 Web API 提供的,严格来说,不是 JavaScript 标准库的一部分。

    你在浏览器环境看到的是 xhr 或者 fetch。在 node.js 环境使用的可能就是 http 或其他什么模块。

    它们底层确实是 C/C++的代码,只是暴露了接口在 JavaScript 引擎内可以通过 API 的方式调用而已

    你可以思考一下,你调用一个 JavaScript 接口到底在干什么。

    可问题是你这个功能需求,跟底层不底层没什么关系
    lolizeppelin
        39
    lolizeppelin  
    OP
       2018-04-16 10:27:29 +08:00
    @tommyZZM
    应该是我表达有误用了底层这个词.....
    我其实也不想关心 socket 接口
    只是因为 fetch 是我见过的第一个没带 http 超时参数的 http 客户端 api
    然后 fetch 又几乎是浏览器端的新标准,我又不熟 JS,所以没办法才想去折腾 socket

    @archliinux
    第一:别人给出了解决方法,您进来就只做嘲讽
    第二:你是真认错了人还是故意随便扣个帽子方便嘲讽?

    @zzNucker
    才学 js 没几天,让您见笑了
    tommyZZM
        40
    tommyZZM  
       2018-04-16 13:19:01 +08:00
    @lolizeppelin

    Web API 的 xhr 和 fetch 都没有超时参数的,原因很简单。

    因为可以通过 js 逻辑进行超时判断,所以规范设计者认为没有必要。

    这个具体细节可以自行查询了解,至于如何实现超时,上面众多 V 友已经给出答复和方案了。

    如果想要了解这个问题的资料,可以轻易的通过 google 查询 timeout、fetch、xmlhttprequest、why 等关键词获取更多你想要的信息。

    嘲讽态度的回复如`只写 js 的前端`、`js 写起来逼疯 `,对你了解这个问题毫无帮助。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2761 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 02:17 · PVG 10:17 · LAX 18:17 · JFK 21:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.