vbscript / Classic ASP - 有没有办法以编程方式获取自己的文件名?

时间:2009-01-16 14:30:42

标签: asp-classic vbscript filenames

我刚刚查看了一些旧代码并发现了以下内容(在foo.asp中):

Const ASP_FILENAME = "foo.asp"  ' TODO: Update this to the name of this file (if changed)

该变量仅用于记录错误。 (即“foo.asp中的错误 - 无法创建xxxxx对象。”)有什么方法可以避免这种情况吗?

谢谢!

4 个答案:

答案 0 :(得分:4)

您可以解析Request.ServerVariables("url")以获取文件名部分。谷歌搜索发现this code,我没有声明信用,它使用SCRIPT_NAME服务器变量,这似乎更有意义,也可以将任何网址重写到可能存在的帐户中:

function getFileName(fpath, returnExtension)
        tmp = fpath
        if instrRev(tmp,"/") > 0 then
              tmp = mid(tmp, instrRev(tmp,"/")+1)
        end if
        if returnExtension = false then
              if instrRev(tmp,".") > 0 then
                    tmp = left(tmp, instrRev(tmp,".")-1)
              end if
        end if
        getFileName = tmp
  end function

  filename = request.ServerVariables("SCRIPT_NAME")
  Const ASP_FILENAME = getFileName(filename, true)

答案 1 :(得分:2)

从现已解散的Aspfaq.com(感谢Archive.org):

如何获取当前网址/网页的名称?

这个很容易,但有两个部分。

要检索当前文件的名称,您可以使用以下任何一种:

<% 
    Response.Write Request.ServerVariables("SCRIPT_NAME") & "<br>" 
    Response.Write Request.ServerVariables("PATH_INFO") & "<br>" 
    Response.Write Request.ServerVariables("URL") & "<br>" 
%>

要使该路径成为本地路径(例如,与FileSystemObject一起使用),只需将server.mappath()方法应用于结果即可。

要获取整个网址,包括http://或https://前缀,您可以执行以下操作:

<% 
    prot = "http" 
    https = lcase(request.ServerVariables("HTTPS")) 
    if https <> "off" then prot = "https" 
    domainname = Request.ServerVariables("SERVER_NAME") 
    filename = Request.ServerVariables("SCRIPT_NAME") 
    querystring = Request.ServerVariables("QUERY_STRING") 
    response.write prot & "://" & domainname & filename & "?" & querystring 
%>

要仅获取页面名称,请使用以下内容:

<% 
    scr = Request.ServerVariables("SCRIPT_NAME") & "<br>" 
    if instr(scr,"/")>0 then 
        scr = right(scr, len(scr) - instrRev(scr,"/")) 
    end if 
    response.write scr 
%>

或者,没有IF逻辑:

<% 
    scr = Request.ServerVariables("SCRIPT_NAME") & "<br>" 
    loc = instrRev(scr,"/") 
    scr = mid(scr, loc+1, len(scr) - loc) 
    response.write scr 
%>

现在。如果你的文件是另一个文件中的#INCLUDE,上面的脚本将产生CALLING文件的名称(因为包含的文件首先被集成到调用脚本中,然后其中的ASP全部在'父文件的上下文中执行) '文件)。解决此问题的一种方法是在加载每个包含文件之前重新填充current_filename变量,例如:

<% 
      current_filename = "filetoinclude.asp" 
 %> 

<!--#include file='filetoinclude.asp'-->

(不,不要尝试将current_filename作为变量传递给#INCLUDE指令;参见文章#2042。)

然后,在filetoinclude.asp中:

<% 
    Response.Write "Current file: " & current_filename 
%>

当然,您可以轻松地对每个包含文件中的文件名进行硬编码。但我认为这种解决方案在某种程度上会破坏至少在某种程度上动态检索信息的目的。

答案 2 :(得分:0)

我不知道传统的asp上是否存在server.mappath,但如果是这样,你可以使用if知道页面文件名。

答案 3 :(得分:0)

不是说这里的任何人[在这里插入离散的喉咙清除咳嗽]仍然使用经典ASP来维护和支持遗留应用程序,但我最近需要做类似的事情。拒绝接受那些“经典ASP不可能”的回应,我开始寻找方法并提出以下解决方案。

这种方法基本上利用底层的OS命令来确定当前文件名(其结果相当于在PHP中使用__FILE__魔术常量),无论它是否是文件包含({ {1}})或脚本本身(*.inc)。

首先,为了支持一些消毒(如果你愿意的话,你可以采取其他一些更“理想”的方式):

*.asp

现在是一段“反思:”

'Regex helpers
Function NewRegex(ByVal pattern, ByVal ignore_case, ByVal global)
  Set NewRegex = New RegExp
  NewRegex.Pattern = pattern
  NewRegex.IgnoreCase = ignore_case
  NewRegex.Global = global
End Function

Function RegexMatch(ByVal pattern, ByVal subject)
  RegexMatch = RegexMatches(subject, pattern, True, False)
End Function

Function RegexMatches(ByVal subject, ByVal pattern, ByVal ignore_case, ByVal global)
  RegexMatches = NewRegex(pattern, ignore_case, global).Test(subject)
End Function

然后,在你要“检查”当前文件名的任何文件中,只需删除以下行,传入一些不应存在于当前目录中任何其他文件中的唯一标识符,但是这一个:

Function GetCurrentFilename(ByVal uniqueId)
  '1. Enforce uniqueId format
  If Not RegexMatch("^[0-9a-f]+$", uniqueId) Then
    Exit Function
  End If

  '2. Use findstr to scan "readable" files in current directory for uniqueId
  Dim shell, cmd, process, fs, filename
  Set shell = Server.CreateObject("WScript.Shell")

  'See findstr /? for details on switches used below
  'cmd = C:\Windows\system32\cmd.exe /c findstr /P /M /C:"uniqueId" "C:\Inetpub\wwwroot\includes\*"
  cmd = shell.ExpandEnvironmentStrings("%COMSPEC%") & " /c findstr /P /M /C:""" & uniqueId & """ """ & Server.MapPath(".") & "\*"""
  Set process = shell.Exec(cmd)

  '3. Use Scripting.FileSystemObject to return the filename portion of the first result returned
  Set fs = Server.CreateObject("Scripting.FileSystemObject")
  GetCurrentFilename = fs.GetFileName(process.StdOut.ReadLine())

  Set fs = Nothing
  Set process = Nothing
  Set shell = Nothing
End Function

结果:

'myfile.inc
Response.Write "This is in " & GetCurrentFilename("908ab098c")

哦,如果你对我需要使用它感兴趣的话,这就是它在简单的断点函数中的用法:

This is in somefile.inc

这样,在我的代码的第20行,如果我想添加自己的断点,它将如下所示:

Function Breakpoint(ByVal line_no, ByVal uniqueId, ByVal msg)
  Dim fn
  fn = GetCurrentFilename(uniqueId)

  Response.Write "[!] Breakpoint hit at Line " & CLng(line_no) & " in " & fn & ": " & Server.HtmlEncode(msg) & vbNewLine
  Response.End
End Function

输出:

Breakpoint 20, "B0001", "Some debug output here"

快乐的编码!