powershell编写一个简易的http服务器httpServer

server/2025/2/4 22:35:53/
http://www.w3.org/2000/svg" style="display: none;">

文章目录

    • powershell一键启动
      • 检查相关进程
    • 源码

powershell一键启动

一键启动脚本内容(powershell,兼容windows powershell和powershell7+)

irm https://gitee.com/xuchaoxin1375/scripts/raw/main/PS/Tools/Tools.psm1|iex
sleep 0.5
help Start-HTTPServer
#可以指定参数选择服务器根目录和端口
start-httpServer

一键启动依赖于互联网,会从gitee下载代码运行

如果要离线运行,参考最后一节,或者部署上述脚本仓库scripts: 实用脚本集合,以powershell模块为主(针对powershell 7开发) 支持一键部署,改善windows下的shell实用体验


如果部署相关仓库pwsh模块,可以使用Start-HttpserverBG来启动一个后台httpServer进程

可以配合一下方法查询相关进程

检查相关进程

@("*pwsh*","*powershell*")|%{ps -Name $_ } |?{$_.CommandLine -like '*httpServer*'}

例如:

@("*pwsh*","*powershell*")|%{ps -Name $_ } |?{$_.CommandLine -like '*httpServer*'}NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName------    -----      -----     ------      --  -- -----------84    45.52     116.32       1.91   12084   2 pwsh

杀死查询结果

ps -Id 12084 |kill

源码

可以跳过不看,如果源码不可用,则可以将下面代码拷贝到powershell的配置文件或者自动导入模块中,然后用powershell命令行收入Start-HttpServer也能离线(不联网)启动本地服务器

更直接的用法是将内容复制保存到一个.ps1脚本文件中,然后通过右键,选择以powershell方式运行(建议用pwsh而非自带的powershell.exe)即可启动服务

windows powershell.exe对于中文(utf8)编码的脚本可能会乱码报错,因此下面的代码纯英文

# If you need to set the service start path, modify the parameters on the last line.
# By default, the desktop is set as the server directory, and the port is 8080.function Format-FileSize
{param([long]$Size)if ($Size -gt 1GB) { return "{0:N2} GB" -f ($Size / 1GB) }if ($Size -gt 1MB) { return "{0:N2} MB" -f ($Size / 1MB) }if ($Size -gt 1KB) { return "{0:N2} KB" -f ($Size / 1KB) }return "$Size B"
}function Get-MimeType
{param([string]$Extension)$MimeTypes = @{".txt"  = "text/plain; charset=utf-8"".ps1"  = "text/plain; charset=utf-8"".py"   = "text/plain; charset=utf-8"".htm"  = "text/html; charset=utf-8"".html" = "text/html; charset=utf-8"".css"  = "text/css; charset=utf-8"".js"   = "text/javascript; charset=utf-8"".json" = "application/json; charset=utf-8"".jpg"  = "image/jpeg"".jpeg" = "image/jpeg"".png"  = "image/png"".gif"  = "image/gif"".pdf"  = "application/pdf"".xml"  = "application/xml; charset=utf-8"".zip"  = "application/zip"".md"   = "text/markdown; charset=utf-8"".mp4"  = "video/mp4"".mp3"  = "audio/mpeg"".wav"  = "audio/wav"}$key = $Extension.ToLower()if ($MimeTypes.ContainsKey($key)){return $MimeTypes[$key]}return "application/octet-stream"
}function Get-DirectoryListing
{param($RelativePath, $Items)$html = @"
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Index of /$RelativePath</title><style>body { font-family: Arial, sans-serif; margin: 20px; }table { border-collapse: collapse; width: 100%; }th, td { text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }th { background-color: #f2f2f2; }tr:hover { background-color: #f5f5f5; }a { text-decoration: none; color: #0066cc; }.size { text-align: right; }.date { white-space: nowrap; }</style>
</head>
<body><h1>Index of /$RelativePath</h1><table><tr><th>Name</th><th class="size">Size</th><th class="date">Last Modified</th></tr>
"@if ($RelativePath){$html += "<tr><td><a href='../'>..</a></td><td></td><td></td></tr>"}# Process folders and files separately and sort by name$Folders = $Items | Where-Object { $_.PSIsContainer } | Sort-Object Name$Files = $Items | Where-Object { !$_.PSIsContainer } | Sort-Object Name# Display folders firstforeach ($Item in $Folders){$Name = $Item.Name$LastModified = $Item.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")$EncodedName = [System.Web.HttpUtility]::UrlEncode($Name)$html += "<tr><td><a href='$EncodedName/'>$Name/</a></td><td class='size'>-</td><td class='date'>$LastModified</td></tr>"}# Display files nextforeach ($Item in $Files){$Name = $Item.Name$Size = Format-FileSize $Item.Length$LastModified = $Item.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")$EncodedName = [System.Web.HttpUtility]::UrlEncode($Name)$html += "<tr><td><a href='$EncodedName'>$Name</a></td><td class='size'>$Size</td><td class='date'>$LastModified</td></tr>"}$html += @"</table><footer style="margin-top: 20px; color: #666; font-size: 12px;">Total $($Folders.Count) folders, $($Files.Count) files</footer>
</body>
</html>
"@return $html
}function Start-HTTPServer
{<#.SYNOPSISStarts a simple HTTP file server..DESCRIPTIONServes a specified local folder as the root directory of an HTTP server, defaulting to port 8080..PARAMETER PathSpecifies the local folder path to be used as the server root directory..PARAMETER PortSpecifies the port number the HTTP server should listen on, defaulting to 8080..EXAMPLEStart-HTTPServer -Path "C:\Share" -Port 8000Serves the C:\Share folder as root at port 8000..EXAMPLEStart-HTTPServerServes the current directory as root at port 8080.#>[CmdletBinding()]param([Parameter(Position = 0)][string]$Path = (Get-Location).Path,[Parameter(Position = 1)][int]$Port = 8080)Add-Type -AssemblyName System.Webtry{# Validate path existsif (-not (Test-Path $Path)){throw "The specified path '$Path' does not exist."}# Create HTTP listener$Listener = New-Object System.Net.HttpListener$Listener.Prefixes.Add("http://+:$Port/")# Try to start the listenertry{$Listener.Start()}catch{throw "Cannot start HTTP server, possibly due to insufficient permissions or port already in use: $_"}Write-Host "HTTP server has started:"Write-Host "Root directory: $Path"Write-Host "Address: http://localhost:$Port/"Write-Host "Press Ctrl+C to stop the server (it may take a few seconds, if you can't wait consider closing the corresponding command line window)"while ($Listener.IsListening){# Wait for request$Context = $Listener.GetContext()$Request = $Context.Request$Response = $Context.Response# URL decode request path$DecodedPath = [System.Web.HttpUtility]::UrlDecode($Request.Url.LocalPath)$LocalPath = Join-Path $Path $DecodedPath.TrimStart('/')# Set response header, support UTF-8$Response.Headers.Add("Content-Type", "text/html; charset=utf-8")# Handle directory requestif ((Test-Path $LocalPath) -and (Get-Item $LocalPath).PSIsContainer){$LocalPath = Join-Path $LocalPath "index.html"if (-not (Test-Path $LocalPath)){# Generate directory listing$Content = Get-DirectoryListing $DecodedPath.TrimStart('/') (Get-ChildItem (Join-Path $Path $DecodedPath.TrimStart('/')))$Buffer = [System.Text.Encoding]::UTF8.GetBytes($Content)$Response.ContentLength64 = $Buffer.Length$Response.OutputStream.Write($Buffer, 0, $Buffer.Length)$Response.Close()continue}}# Handle file requestif (Test-Path $LocalPath){$File = Get-Item $LocalPath$Response.ContentType = Get-MimeType $File.Extension$Response.ContentLength64 = $File.Length# Add filename encoding support$FileName = [System.Web.HttpUtility]::UrlEncode($File.Name)$Response.Headers.Add("Content-Disposition", "inline; filename*=UTF-8''$FileName")$FileStream = [System.IO.File]::OpenRead($File.FullName)$FileStream.CopyTo($Response.OutputStream)$FileStream.Close()}else{# Return 404$Response.StatusCode = 404$Content = "404 - File not found"$Buffer = [System.Text.Encoding]::UTF8.GetBytes($Content)$Response.ContentLength64 = $Buffer.Length$Response.OutputStream.Write($Buffer, 0, $Buffer.Length)}$Response.Close()}}finally{if ($Listener){$Listener.Stop()$Listener.Close()}}
}function Start-HTTPServerBG
{param (# Default shell is Windows PowerShell, if PowerShell 7+ (or pwsh) is installed, use pwsh instead;# By default, need to add Start-HTTPServer to PowerShell configuration file or PowerShell auto-import module, otherwise Start-HTTPServerBG command will not be available, leading to start failure.# $shell = "powershell",$shell = "pwsh", # Personally prefer pwsh$path = "$home\Desktop",$Port = 8080)Write-Verbose "Trying to start HTTP server..." -Verbose# $PSBoundParameters $params = [PSCustomObject]@{shell = $shellpath  = $pathPort  = $Port}Write-Output $params # Cannot directly output literal object with Write-Output, it will be treated as a string# Write-Output $shell, $path, $Port# $exp = "Start-Process -WindowStyle Hidden -FilePath $shell -ArgumentList { {c Start-HTTPServer -path $path -port $Port } -PassThru"# Write-Output $exp# $ps = $exp | Invoke-Expression# $func = ${Function:Start-HTTPServer} # Since the complete code of Start-HTTPServer is too scattered, just writing this way cannot obtain the complete Start-HTTPServer function$ps = Start-Process -FilePath $shell -ArgumentList "-c Start-HTTPServer -path $path -port $Port" -PassThru# Debug start-process syntax# $ps = Start-Process -FilePath pwsh -ArgumentList "-c", "Get-Location;Pause "return $ps}# Modify as needed
Start-HTTPServer -Path "$home\Desktop" -Port 8080

http://www.ppmy.cn/server/164998.html

相关文章

Oracle Primavera P6 最新版 v24.12 更新 2/2

目录 一. 引言 二. P6 EPPM 更新内容 1. 用户管理改进 2. 更轻松地标准化用户设置 3. 摘要栏标签汇总数据字段 4. 将里程碑和剩余最早开始日期拖到甘特图上 5. 轻松访问审计数据 6. 粘贴数据时排除安全代码 7. 改进了状态更新卡片视图中的筛选功能 8. 直接从活动电子…

项目测试之Postman

文章目录 基础实战进行批量测试并输出报告 基础 实战 进行批量测试并输出报告 参考&#xff1a; https://blog.csdn.net/tyh_keephunger/article/details/109205191 概述 Newman是什么&#xff1f;Newman是Postman的命令行工具&#xff0c;用于执行接口测试集合。操作过程…

基于PostgreSQL的自然语义解析电子病历编程实践与探索(上)

一、引言 1.1研究目标与内容 本研究旨在构建一个基于 PostgreSQL 的自然语义解析电子病历编程体系,实现从电子病历文本中提取结构化信息,并将其存储于 PostgreSQL 数据库中,以支持高效的查询和分析。具体研究内容包括: 电子病历的预处理与自然语言处理:对电子病历文本进…

新月军事战略分析系统使用手册

新月人物传记&#xff1a; 人物传记之新月篇-CSDN博客 相关故事链接&#xff1a;星际智慧农业系统&#xff08;SAS&#xff09;&#xff0c;智慧农业的未来篇章-CSDN博客 “新月智能武器系统”CIWS&#xff0c;开启智能武器的新纪元-CSDN博客 “新月之智”智能战术头盔系统&…

汽车中控屏HMI界面,安全和便捷是设计的两大准则。

在汽车智能化的浪潮中&#xff0c;汽车中控屏 HMI&#xff08;Human - Machine Interface&#xff0c;人机交互界面&#xff09;界面已成为车辆与驾驶者沟通的关键桥梁。它不仅集成了众多车辆功能的控制&#xff0c;还承担着信息展示与交互的重任。而在其设计过程中&#xff0c…

MATLAB中的IIR滤波器设计

在数字信号处理中&#xff0c;滤波器是消除噪声、提取特征或调整信号频率的核心工具。其中&#xff0c;无限脉冲响应&#xff08;IIR&#xff09;滤波器因其低阶数实现陡峭滚降的特性&#xff0c;被广泛应用于音频处理、通信系统和生物医学工程等领域。借助MATLAB强大的工具箱&…

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)

目录 1 -> 生命周期 1.1 -> 应用生命周期 1.2 -> 页面生命周期 2 -> 资源限定与访问 2.1 -> 资源限定词 2.2 -> 资源限定词的命名要求 2.3 -> 限定词与设备状态的匹配规则 2.4 -> 引用JS模块内resources资源 3 -> 多语言支持 3.1 -> 定…

网络编程套接字(中)

文章目录 &#x1f34f;简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求客户端创建套接字客户端连接服务器客户端发起请求服务器测试单执行流服务器的弊端 &#x1f350;多进程版的TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务 &#x1…