WinForms 的支持跨域的测试程序
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace SimpleHttpServer_cors
{
public partial class Form1 : Form
{
private HttpListener listener;
private Thread listenerThread;
private bool isStopping = false; // 标志位,用于指示服务是否正在停止
public Form1()
{
InitializeComponent();
this.FormClosing += Form1_FormClosing; // 订阅窗体关闭事件
txtIPAddress.Text = GetLocalIP();
}
private void btnStartService_Click(object sender, EventArgs e)
{
string ipAddress = txtIPAddress.Text;
string port = txtPort.Text;
listener = new HttpListener();
listener.Prefixes.Add($"http://{ipAddress}:{port}/");
listenerThread = new Thread(StartListener);
listenerThread.Start();
MessageBox.Show("服务已启动");
}
private void StartListener()
{
listener.Start();
while (listener.IsListening)
{
try
{
var context = listener.GetContext();
ThreadPool.QueueUserWorkItem(o => HandleRequest(context));
}
catch (HttpListenerException)
{
// 监听器已停止
break;
}
}
}
private void HandleRequest(HttpListenerContext context)
{
string responseString = string.Empty;
if (context.Request.HttpMethod == "GET" && context.Request.Url.AbsolutePath == "/getapi/getadate/test2")
{
responseString = "{\"sites\":[{\"name\":\"菜鸟教程\",\"get_url\":\"www.runoob.com\"},{\"name\":\"google\",\"get_url\":\"www.google.com\"},{\"name\":\"微博\",\"get_url\":\"www.weibo.com\"}]}";
}
else if (context.Request.HttpMethod == "POST" && context.Request.Url.AbsolutePath == "/postapi/test1")
{
using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
{
string requestData = reader.ReadToEnd();
Console.WriteLine($"Received POST data: {requestData}");
}
responseString = "{\"sites\":[{\"name\":\"菜鸟教程\",\"post_url\":\"www.runoob.com\"},{\"name\":\"google\",\"post_url\":\"www.google.com\"},{\"name\":\"微博\",\"post_url\":\"www.weibo.com\"}]}";
}
//跨域的
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
}
private void btnStopService_Click(object sender, EventArgs e)
{
StopService();
}
private void StopService()
{
if (listener != null && listener.IsListening)
{
isStopping = true;
listener.Stop();
listener.Close();
listenerThread.Join();
MessageBox.Show("服务已暂停");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopService(); // 确保在窗体关闭时停止服务
}
/// <summary>
/// 获取当前使用的IP
/// </summary>
/// <returns></returns>
public string GetLocalIP()
{
string result = RunApp("route", "print", true);
Match m = Regex.Match(result, @"0.0.0.0\s+0.0.0.0\s+(\d+.\d+.\d+.\d+)\s+(\d+.\d+.\d+.\d+)");
if (m.Success)
{
return m.Groups[2].Value;
}
else
{
try
{
System.Net.Sockets.TcpClient c = new System.Net.Sockets.TcpClient();
c.Connect("www.baidu.com", 80);
string ip = ((System.Net.IPEndPoint)c.Client.LocalEndPoint).Address.ToString();
c.Close();
return ip;
}
catch (Exception)
{
return null;
}
}
}
/// <summary>
/// 运行一个控制台程序并返回其输出参数。
/// </summary>
/// <param name="filename">程序名</param>
/// <param name="arguments">输入参数</param>
/// <returns></returns>
public string RunApp(string filename, string arguments, bool recordLog)
{
try
{
if (recordLog)
{
Trace.WriteLine(filename + " " + arguments);
}
Process proc = new Process();
proc.StartInfo.FileName = filename;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.Arguments = arguments;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
using (System.IO.StreamReader sr = new System.IO.StreamReader(proc.StandardOutput.BaseStream, Encoding.Default))
{
Thread.Sleep(100); //貌似调用系统的nslookup还未返回数据或者数据未编码完成,程序就已经跳过直接执行
//txt = sr.ReadToEnd()了,导致返回的数据为空,故睡眠令硬件反应
if (!proc.HasExited) //在无参数调用nslookup后,可以继续输入命令继续操作,如果进程未停止就直接执行
{ //txt = sr.ReadToEnd()程序就在等待输入,而且又无法输入,直接掐住无法继续运行
proc.Kill();
}
string txt = sr.ReadToEnd();
sr.Close();
if (recordLog)
Trace.WriteLine(txt);
return txt;
}
}
catch (Exception ex)
{
Trace.WriteLine(ex);
return ex.Message;
}
}
}
}
需要在防火墙的规则中添加对应的端口:
在另外一个电脑中访问:
1:启动服务
2:展示一下另外一个电脑的IP地址
3:在浏览器中进行请求
4:请求完成显示信息
使用的html文件源码
需要修改代码中的IP地址:localhost 修改为服务器的IP地址。
<!DOCTYPE html>
<html>
<head>
<title>CORS Test</title>
</head>
<body>
<button onclick="fetchData()">Fetch Data</button>
<div id="result"></div>
<script>
function fetchData() {
fetch('http://localhost:18792/getapi/getadate/test2')
.then(response => response.json())
.then(data => {
document.getElementById('result').innerText = JSON.stringify(data, null, 2);
})
.catch(error => console.error('Error:', error));
}
</script>
</body>
</html>