R中通过URL访问本地文件遇问题:safedata本地服务器请求挂起
解决R中访问本地servr服务器挂起及简化本地文件URL访问的方案
先解决当前servr挂起的问题
你遇到的挂起问题,大概率是因为servr默认在阻塞模式运行:当你在当前R会话里启动servr(比如用servr::httw()),这个会话会被服务器占用,没法同时执行httr::GET请求——浏览器能访问是因为服务器确实在跑,但R会话被卡住了。
解决方法很简单,把servr放到后台独立进程运行,比如用callr包:
library(callr) # 启动后台servr,指定包inst目录下的api文件夹作为静态文件根目录 servr_process <- r_bg(function() { servr::httw(dir = system.file("api", package = "safedata"), port = 4321) }) # 给服务器一点启动时间 Sys.sleep(2) # 现在可以正常发送请求了 library(httr) resp <- GET("http://127.0.0.1:4321/api/index.json") content(resp) # 测试结束后记得关掉后台进程 servr_process$kill()
更简单的替代方案:不用搭服务器
其实你完全没必要搭本地服务器,有两种更轻量的方式:
方案1:直接用file://协议访问本地文件
如果你的包代码支持file://开头的URL,直接把本地文件路径转成对应格式就行:
library(httr) # 获取包inst目录下目标文件的绝对路径 file_path <- system.file("api/index.json", package = "safedata") # 转换成file://格式(自动适配Windows和Linux/macOS) file_url <- if (.Platform$OS.type == "windows") { paste0("file:///", gsub("\\\\", "/", file_path)) } else { paste0("file://", file_path) } # 直接请求即可 resp <- GET(file_url) content(resp)
方案2:用Mock工具拦截请求(适合测试场景)
如果你的测试需要模拟真实的API域名(不想改URL),可以用请求Mock工具直接拦截请求,返回本地文件内容,完全不需要服务器:
比如用webmockr包:
library(webmockr) library(httr) # 开启mock功能 webmockr::enable() # 拦截你原本要请求的元数据服务器URL,返回本地文件内容 stub_request("get", "http://your-meta-server/api/index.json") %>% to_return( body = readLines(system.file("api/index.json", package = "safedata")), status = 200, headers = list("Content-Type" = "application/json") ) # 现在发送请求会直接返回mock的内容,和真实服务器响应完全一致 resp <- GET("http://your-meta-server/api/index.json") content(resp) # 测试完记得关闭mock webmockr::disable()
内容的提问来源于stack exchange,提问作者David_O
相关产品推荐
相关产品推荐

