1. 远程开发时,那个烦人的XHR failed弹窗

不知道你有没有遇到过这种情况:兴致勃勃地想用VSCode连上远程服务器开始写代码,结果刚连接,VSCode就开始在远程服务器上吭哧吭哧地下载安装“VSCode Server”。进度条走了一会儿,突然弹出一个错误提示——“XHR failed”。然后连接就中断了,留下你一个人对着屏幕发呆。

这个“XHR failed”错误,说白了就是VSCode在尝试从它的官方服务器下载必要的远程组件时,网络请求失败了。XHR(XMLHttpRequest)是一种浏览器技术,VSCode的底层通信也会用到它。当你在本地点击“连接到远程主机”时,VSCode会尝试在远程服务器的 ~/.vscode-server/bin/ 目录下,安装一个与本地VSCode版本完全匹配的“服务端”。这个过程需要从微软的更新服务器(通常是 update.code.visualstudio.com)拉取一个压缩包。如果你的远程服务器位于国内,或者所在网络环境访问这些海外服务器不稳定、速度慢甚至被阻断,这个下载请求就很容易超时或失败,从而触发“XHR failed”。

我刚开始用远程开发的时候,就被这个问题卡住过好几次。尤其是在一些公司内网的开发机,或者某些云服务商的海外节点上,这个问题出现的概率相当高。它不像代码错误有明确的堆栈信息,就是一个简单的网络请求失败,让人有点无从下手。但别担心,这个问题其实有非常直接和高效的解决套路,根本不需要你去折腾复杂的网络配置。下面我就把自己踩过坑后总结出来的、实测最稳的方法,一步步分享给你。

2. 核心思路:手动“送货上门”

VSCode远程连接的核心,就是在远程服务器上安装一个版本号(COMMIT_ID)完全一致的Server端。自动安装失败,本质是网络不行。那我们的解决思路就非常“物理”了:既然服务器自己“取”不到,那我们就手动“送”上去。

这个方法的精髓在于,我们完全绕开VSCode那个不稳定的自动下载流程。我们自己找到正确版本的vscode-server-linux-x64.tar.gz文件,手动下载到本地,然后通过SCP等工具上传到远程服务器,再手动解压到正确的目录。整个过程,就像给一个断网的朋友送安装包一样直接。我实测下来,这个方法成功率接近100%,而且一旦配置好,后续只要VSCode本体不升级,这个服务端就能一直用。

这里最关键的一个东西就是 COMMIT_ID。你可以把它理解为VSCode某个具体版本的唯一身份证号。本地VSCode和远程VSCode Server必须凭这个“身份证”对上了,才能成功握手建立连接。所以,我们第一步就是要找到你自己电脑上VSCode对应的这个ID。

2.1 第一步:找到你的“身份凭证”(COMMIT_ID)

这个ID其实就藏在VSCode里,有不止一种方法可以查到。我推荐两种最直接的方法:

方法一:通过VSCode帮助菜单(最推荐)

  1. 在你本地的VSCode中,点击顶部菜单栏的 帮助
  2. 在下拉菜单中选择 关于
  3. 在弹出的关于窗口中,仔细找一行类似 版本: 1.86.0 的信息,在这行信息的末尾,括号里的一长串字母数字组合,就是我们要的 COMMIT_ID。例如:(e57c4de...)e57c4de...这一串就是。

方法二:通过连接失败时的错误日志(备用) 如果第一次连接已经失败并弹出“XHR failed”,其实错误输出里也包含了这个ID。你可以点击错误弹窗上的“详细资料”或“打开日志”,在日志文件里搜索 commit id 字样,也能找到它。

记下这个ID,它是一串类似于 e57c4de76d6e2ea2210c991d36bce8bb249a6d9a 的哈希值。接下来所有步骤都要用到它。

2.2 第二步:获取正确的服务器安装包

知道了COMMIT_ID,我们就知道了该下载哪个版本的服务端文件。微软官方将编译好的服务端文件放在了CDN上。一个常用的、在国内访问速度相对较快的镜像地址是 vscode.cdn.azure.cn

你需要拼接出完整的下载链接,格式如下:

https://vscode.cdn.azure.cn/stable/你的COMMIT_ID/vscode-server-linux-x64.tar.gz

例如,如果你的COMMIT_ID是 e57c4de76d6e2ea2210c991d36bce8b249a6d9a,那么下载链接就是:

https://vscode.cdn.azure.cn/stable/e57c4de76d6e2ea2210c991d36bce8b249a6d9a/vscode-server-linux-x64.tar.gz

这里有个非常重要的细节: 你需要在网络通畅的环境下下载这个文件。通常,你本地的电脑网络访问这个CDN是没问题的。所以,不要试图在远程服务器上执行wgetcurl命令来下载,因为可能正是远程服务器的网络不行才导致的问题。正确的做法是:用你自己的浏览器或者本机的下载工具,把上面这个链接里的文件下载到你的本地电脑上。

如果万一这个镜像地址也访问不了,你还可以尝试替换域名部分为官方的 update.code.visualstudio.com,但速度可能更慢。我个人的经验是,Azure的CDN镜像对于国内用户来说已经是最优选择了。

3. 手动部署:把“服务端”送上服务器

现在,你本地电脑上已经有了一个 vscode-server-linux-x64.tar.gz 文件。接下来,我们要把它搬运到远程服务器,并放到正确的“房间”(目录)里。

3.1 第三步:上传文件到远程服务器

你需要使用文件传输工具,比如 scp(命令行)或者 FileZilla(图形化界面)。这里以最通用的 scp 命令为例。

打开你本地的终端(比如Mac的Terminal,Windows的PowerShell或WSL),执行以下命令:

scp /本地路径/vscode-server-linux-x64.tar.gz 你的用户名@远程服务器IP:~/

例如:

scp ./Downloads/vscode-server-linux-x64.tar.gz developer@192.168.1.100:~/

这个命令会把本地的压缩包,上传到远程服务器的用户家目录(~)下。

3.2 第四步:在服务器上执行解压和安置

现在,通过SSH连接到你的远程服务器:

ssh 你的用户名@远程服务器IP

登录成功后,依次执行以下命令。请务必将下面命令中的 COMMIT_ID 替换成你之前记录的那一串真实ID

  1. 创建VSCode Server的目标目录: VSCode期望的服务端文件存放在 ~/.vscode-server/bin/COMMIT_ID/ 这个路径下。我们直接创建它。

    mkdir -p ~/.vscode-server/bin/你的COMMIT_ID
    

    例如:mkdir -p ~/.vscode-server/bin/e57c4de76d6e2ea2210c991d36bce8b249a6d9a

  2. 解压我们上传的安装包: 我们之前把压缩包上传到了家目录。现在解压它。注意,这个压缩包解压后会直接得到一个名为 vscode-server-linux-x64 的文件夹,里面就是所有文件。

    tar -zxf ~/vscode-server-linux-x64.tar.gz -C ~/.vscode-server/bin/你的COMMIT_ID --strip-components 1
    

    这个命令的妙处在于:

    • -zxf:解压gz压缩包。
    • -C:指定解压目标目录为刚创建的那个带COMMIT_ID的目录。
    • --strip-components 1:这是关键!它会去掉压缩包内第一层目录(即vscode-server-linux-x64这个文件夹本身),直接将文件夹内的所有内容解压到目标目录。这样,bin/COMMIT_ID/ 目录下直接就是 nodeserver.shout 等运行时需要的文件,结构完全符合VSCode的预期。

    你也可以分两步操作,效果一样:

    # 先解压到家目录下临时文件夹
    tar -zxf ~/vscode-server-linux-x64.tar.gz -C ~/
    # 然后将解压出的文件夹内容,移动到目标目录
    mv ~/vscode-server-linux-x64/* ~/.vscode-server/bin/你的COMMIT_ID/
    # 最后清理临时空文件夹
    rmdir ~/vscode-server-linux-x64
    

3.3 第五步:验证与最终连接

安置完成后,强烈建议检查一下文件是否就位。

ls -la ~/.vscode-server/bin/你的COMMIT_ID/

你应该能看到类似 nodeserver.shoutpackage.json 等文件和文件夹。如果目录是空的或者只有个别文件,说明上一步的解压移动可能出错了。

现在,最关键的一步来了:完全关闭你本地所有的VSCode窗口。然后重新打开VSCode,再次通过Remote-SSH尝试连接你的远程服务器。

这一次,VSCode在连接时,会检测远程服务器上 ~/.vscode-server/bin/你的COMMIT_ID/ 目录。当它发现所需版本的Server端已经完整存在,就会跳过漫长的下载过程,直接启动这个本地的Server进程。你会看到连接进度条飞快地走完,然后成功进入远程工作区。那个恼人的“XHR failed”错误,就这么被我们手动操作化解了。

4. 进阶排查与预防措施

按照上面的步骤,90%的XHR失败问题都能解决。但如果万一还是没成功,或者你想更深入地理解并预防这个问题,我们可以再往下挖一挖。

4.1 检查目录权限与所有者

有时候问题不出在文件是否存在,而出在“能不能执行”。VSCode Server启动时需要执行 node 等二进制文件。请确保你放置文件的目录权限正确。通常,你的用户需要有读、写、执行权限。可以通过以下命令检查和修正:

# 检查权限
ls -ld ~/.vscode-server/bin/
ls -ld ~/.vscode-server/bin/你的COMMIT_ID/
# 如果权限不对(例如所属用户是root),修正为当前用户
sudo chown -R $(whoami):$(whoami) ~/.vscode-server
# 确保目录和文件有可执行权限(通常解压后已有)
chmod -R u+rx ~/.vscode-server/bin/你的COMMIT_ID/

权限问题在多人共用服务器或者之前用sudo操作过相关目录时可能出现。

4.2 理解并配置下载镜像源

VSCode允许我们配置一个稳定的下载镜像源,来替代默认的官方服务器。这对于团队内部或者长期在固定网络环境下工作非常有用。你可以在远程服务器的SSH配置文件中设置一个环境变量。

编辑或创建文件 ~/.ssh/config(在本地电脑上),针对你的远程主机添加如下配置:

Host my-remote-server
    HostName 你的服务器IP
    User 你的用户名
    # 关键配置:设置VSCode Server的下载镜像
    RemoteCommand VSCODE_SERVER_DOWNLOAD_URL=https://vscode.cdn.azure.cn/stable/%commit%/vscode-server-linux-x64.tar.gz /bin/bash
    RequestTTY force

这个配置告诉VSCode,当需要下载Server时,使用我们指定的Azure镜像地址。%commit% 是一个变量,VSCode会自动替换为对应的COMMIT_ID。这样配置后,即使未来VSCode升级需要新版本的Server,它也会尝试从这个更稳定的镜像下载,可能从源头上避免XHR失败。

4.3 清理旧版本与缓存

如果你多次尝试连接失败,远程服务器的 .vscode-server 目录下可能会残留一些不完整或旧版本的安装缓存。这些残留物有时会干扰新版本的正常安装。在尝试手动部署前,可以先彻底清理一下:

# 谨慎操作!这会删除所有已安装的VSCode Server端
rm -rf ~/.vscode-server

执行后,再完全按照第二节、第三节的步骤重新进行手动部署。一个干净的环境往往能避免很多诡异的问题。

5. 总结一下关键要点与个人心得

回顾整个过程,解决“XHR failed”的核心就是 “手动替代自动”。我们主动获取版本号,主动下载安装包,主动部署到指定位置,从而绕开了网络下载这个最不稳定的环节。

我印象最深的一次,是在给一个团队的新服务器配置统一开发环境时,十几台服务器几乎全都卡在XHR下载这里。如果一台台去排查网络策略、代理设置,那将是个噩梦。而我们采用的就是这个手动部署方案:在一台网络好的机器上下载好安装包,然后写了个简单的脚本,用scpssh批量分发、解压到所有服务器上。半个小时,所有人的VSCode远程连接就全部就绪了,效率非常高。

所以,以后再看到VSCode远程连接弹出“XHR failed”,别慌。你就把它看作是一个简单的“文件搬运”任务。找到ID,下载包,传上去,解压好,就这么四步。这套方法不仅解决了问题,也让你对VSCode远程开发的底层机制有了更直观的理解。毕竟,知其然也知其所以然,解决问题才能更从容。

更多推荐