繁体   English   中英

R shiny 将文件输入限制为文件名模式,而不仅仅是文件类型

[英]R shiny restrict fileInput to filename pattern and not just file type

我有一个 Shiny 应用程序,它使用fileInput在客户端获取一些文件(我不能使用在服务器端管理文件的 shinyFiles package)。

我希望用户只能上传与特定模式匹配的文件(例如helloWorld.txt ),而不仅仅是匹配文件类型(例如文本、csv 等)。

fileInput有一个accept参数,您可以在其中提供接受的文件类型。 从文档:

accept  A character vector of MIME types; gives the browser a hint of 
        what kind of files the server is expecting.

我不只是想指定接受的文件类型,这对我的应用程序来说不够严格。 有没有办法做到这一点?

这是一个只接受文本文件的 MWE:

library(shiny)

ui <- fluidPage(
    fileInput(
        "file_choice",
        label = "Choose a files", 
        multiple = TRUE,
        accept = c(
            ".txt"
        )
    )
)

server <- function(input, output, session) {}

shinyApp(ui, server)

如果我使用:

accept = c(
    "helloWorld.txt"
)

它不起作用,因为它不是 MIME 类型。

此页面Shiny 文件输入参数“接受”问题建议在服务器端之后处理所选文件,这是我最终要做的,但我更喜欢先验限制而不是后验限制(以避免服务器端文件检查并反馈给用户)。

一种方法是插入一些 javascript 作为onchange事件触发器,检查文件名,如果不匹配,则中断上传过程。 这种方法使用alert ,我知道很多人认为这种方法有点侵入性并且不美观,我相信其他人可以提出更好的建议。

我应该从一个简单的警告开始:这里的条件严格来说是“文件以文字hello开头” 您的示例可能需要更多技巧,而不是需要文件名 sans-extension 匹配。 在这种情况下,可能需要正则表达式,请参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 之类的内容以获取更多信息。 这个答案提供的是一个框架供您填补漏洞。

(在修改此代码时,您可能会发现添加alert(FileName)和/或alert(FileBase)以查看 javascript 与您的模式进行比较很有用。每次尝试都会弹出。在我的例子中,它帮助我发现毫不奇怪,存在 windows 路径,这意味着它使用反斜杠而不是正斜杠,需要split(/[\\/]/) ,进一步转义为 R。)

checkjs <- 'function checkFileName(fieldObj) {
    var FileName  = fieldObj.value;
    var FileBase = FileName.split(/[\\\\/]/).pop();
    if (! FileBase.startsWith("hello")) {
        fieldObj.value = "";
        alert("File does not start with hello");
        return false;
    }
    return true;
}'

attrib_replace <- function(x, cond, ...) {
  if (all(names(cond) %in% names(x)) && identical(cond, x[names(cond)])) x <- c(x, list(...))
  if ("attribs" %in% names(x)) x$attribs <- attrib_replace(x$attribs, cond = cond, ...)
  if ("children" %in% names(x)) x$children <- lapply(x$children, function(ch) attrib_replace(ch, cond = cond, ...))
  x
}

一个示例应用程序,使用它:

library(shiny)
shinyApp(
  ui = fluidPage(
    tags$script(checkjs),
    attrib_replace(fileInput(
        "file_choice",
        label = "Choose a file",
        multiple = TRUE,
        accept = c(".txt")
    ), list(id = "file_choice", type = "file"), onchange = "checkFileName(this);")
  ),
  server = function(input, output, session) {}
)

闪亮的应用程序显示中断文件上传

当您 select 文件不以“hello”开头时,它会发出警报并且不会上传文件。 正确的文件只上传文件。

我为此引用的其他一些答案:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM