You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我复制的PowerShell HTTP服务器代码无法正常运行?

解决PowerShell简易Web服务器访问index.html出现404的问题

你的问题很清晰——运行这段PowerShell代码搭建Web服务器后,访问http://localhost:8080/index.html出现404错误,核心原因是这段代码根本没处理/index.html的请求,也没有读取本地文件的逻辑,我来给你拆解问题和修复方案:

代码问题分析

原代码的核心逻辑是通过$htmlcontents哈希表硬编码匹配请求路径:

  • 只预设了GET /(根路径)和GET /services两个请求的返回内容
  • 当收到的请求不在这个哈希表里时,直接返回404错误
  • 完全没有读取本地index.html文件的逻辑,哪怕你把代码放在有这个文件的目录里也无法识别

修复方案

根据你的需求,我提供两种修复思路,你可以根据场景选择:

方案1:仅支持根路径和/index.html返回本地index.html

修改$htmlcontents哈希表,添加对GET /index.html的映射,同时读取本地文件内容:

# enter this URL to reach PowerShell’s web server 
$url = 'http://localhost:8080/' 
# HTML content for some URLs entered by the user 
$htmlcontents = @{ 
    'GET /' = Get-Content index.html -Raw  # 读取本地index.html文件作为根路径返回
    'GET /index.html' = Get-Content index.html -Raw  # 匹配/index.html请求
    'GET /services' = Get-Service | ConvertTo-Html 
} 
# start web server 
$listener = New-Object System.Net.HttpListener 
$listener.Prefixes.Add($url) 
$listener.Start() 
try { 
    while ($listener.IsListening) { 
        # process received request 
        $context = $listener.GetContext() 
        $Request = $context.Request 
        $Response = $context.Response 
        $received = '{0} {1}' -f $Request.httpmethod, $Request.url.localpath 
        # is there HTML content for this URL? 
        $html = $htmlcontents[$received] 
        if ($html -eq $null) { 
            $Response.statuscode = 404 
            $html = 'Oops, the page is not available!' 
        } 
        # return the HTML to the caller 
        $buffer = [Text.Encoding]::UTF8.GetBytes($html) 
        $Response.ContentLength64 = $buffer.length 
        $Response.OutputStream.Write($buffer, 0, $buffer.length) 
        $Response.Close() 
    } 
} finally { 
    $listener.Stop() 
}

方案2:支持任意静态文件访问(更灵活)

如果想让服务器能处理更多静态文件(比如css、js、其他html),可以修改逻辑,自动识别请求路径对应的本地文件:

# enter this URL to reach PowerShell’s web server 
$url = 'http://localhost:8080/' 
$webRoot = Get-Location  # 当前目录作为网站根目录
# start web server 
$listener = New-Object System.Net.HttpListener 
$listener.Prefixes.Add($url) 
$listener.Start() 
try { 
    while ($listener.IsListening) { 
        # process received request 
        $context = $listener.GetContext() 
        $Request = $context.Request 
        $Response = $context.Response 
        $requestPath = $Request.url.localpath 
        
        # 根路径默认返回index.html
        if ($requestPath -eq '/') {
            $requestPath = '/index.html'
        }
        
        # 构建本地文件路径,防止路径遍历攻击
        $localPath = Join-Path -Path $webRoot -ChildPath $requestPath.TrimStart('/')
        $localPath = [System.IO.Path]::GetFullPath($localPath)
        
        # 检查文件是否存在且在网站根目录内
        if ($localPath.StartsWith($webRoot) -and (Test-Path $localPath -PathType Leaf)) {
            try {
                $content = Get-Content $localPath -Raw
                $buffer = [Text.Encoding]::UTF8.GetBytes($content)
                $Response.ContentLength64 = $buffer.length
                $Response.OutputStream.Write($buffer, 0, $buffer.length)
            } catch {
                $Response.statuscode = 500
                $html = 'Error reading file!'
                $buffer = [Text.Encoding]::UTF8.GetBytes($html)
                $Response.ContentLength64 = $buffer.length
                $Response.OutputStream.Write($buffer, 0, $buffer.length)
            }
        } else {
            # 保留services特殊请求的处理
            if ($Request.httpmethod -eq 'GET' -and $requestPath -eq '/services') {
                $html = Get-Service | ConvertTo-Html
                $buffer = [Text.Encoding]::UTF8.GetBytes($html)
                $Response.ContentLength64 = $buffer.length
                $Response.OutputStream.Write($buffer, 0, $buffer.length)
            } else {
                $Response.statuscode = 404
                $html = 'Oops, the page is not available!'
                $buffer = [Text.Encoding]::UTF8.GetBytes($html)
                $Response.ContentLength64 = $buffer.length
                $Response.OutputStream.Write($buffer, 0, $buffer.length)
            }
        }
        
        $Response.Close()
    } 
} finally { 
    $listener.Stop() 
}

这个方案不仅能返回index.html,还能处理其他静态文件,同时加入了路径遍历防护,更安全实用。

内容的提问来源于stack exchange,提问作者user310291

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:15:31