Files
KJD_WebService/Store.Framework/Utils/HtmlUtils.cs
T
chfei fa03add754 增加同步物流模块
修改现有架构,改为分模块( 简易版)
2026-09-22 17:52:42 +08:00

415 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
namespace KJD_Web.Utils
{
public class HtmlUtils
{
static public string UrlDecodeUtf8(string value)
{
if (value == null)
{
return null;
}
Encoding encoding = Encoding.UTF8;//你的编码 也可能是GBK
int length = value.Length;
UrlDecoder decoder = new UrlDecoder(length, encoding);
for (int i = 0; i < length; i++)
{
char ch = value[i];
if (ch == '+')
{
ch = ' ';
}
else if ((ch == '%') && (i < (length - 2)))
{
if ((value[i + 1] == 'u') && (i < (length - 5)))
{
int num3 = HexToInt(value[i + 2]);
int num4 = HexToInt(value[i + 3]);
int num5 = HexToInt(value[i + 4]);
int num6 = HexToInt(value[i + 5]);
if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0)))
{
goto Label_010B;
}
ch = (char)((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6);
i += 5;
decoder.AddChar(ch);
continue;
}
int num7 = HexToInt(value[i + 1]);
int num8 = HexToInt(value[i + 2]);
if ((num7 >= 0) && (num8 >= 0))
{
byte b = (byte)((num7 << 4) | num8);
i += 2;
decoder.AddByte(b);
continue;
}
}
Label_010B:
if ((ch & 0xff80) == 0)
{
decoder.AddByte((byte)ch);
}
else
{
decoder.AddChar(ch);
}
}
return decoder.GetString();
}
/// <summary>
/// URL UTF-8转码
/// </summary>
/// <param name="IndexKey"></param>
/// <returns></returns>
public static string UrlEncodeUtf8(string IndexKey)
{
if (String.IsNullOrEmpty(IndexKey))
return "";
return HttpUtility.UrlEncode(IndexKey, Encoding.UTF8);
}
/// <summary>
/// post 数据
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <returns></returns>
public static string PostUtf8(string url, StringBuilder postData)
{
try
{
WebClientx wc = new WebClientx();
byte[] sendData = Encoding.GetEncoding("utf-8").GetBytes(postData.ToString());
wc.Headers.Add("ContentLength", sendData.Length.ToString());
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.Proxy = null;
return Encoding.UTF8.GetString(wc.UploadData(url, "POST", sendData));
}
catch
{
return "";
}
}
/// <summary>
/// 浏览器标识
/// </summary>
public static string UserAgent = @"Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36
Mozilla/5.0+(Windows+NT+6.1)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36
Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/54.0.2840.99+Safari/537.36
Mozilla/5.0+(Windows+NT+5.1)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36
Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.1;+Win64;+x64;+Trident/5.0)
Mozilla/5.0+(Windows+NT+5.1)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.101+Safari/537.36
Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.101+Safari/537.36
Mozilla/5.0+(Windows+NT+6.3;+WOW64;+Trident/7.0;+rv:11.0)+like+Gecko
Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36
Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.1;+WOW64;+Trident/5.0)
Mozilla/5.0+(Windows+NT+6.3;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36
Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.1+(KHTML,+like+Gecko)+Chrome/21.0.1180.89+Safari/537.1
Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.101+Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2372.400 QQBrowser/9.5.10548.400";
/// <summary>
/// post 数据
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <returns></returns>
public static string PostUtf8(string url, string postData, string contentType = "")
{
//return PostUtf8(url, Encoding.UTF8.GetBytes(postData));
bool isError = false;
string[] l = UserAgent.Split('\n');
reTry:
try
{
string codeType = "utf-8";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = l[new Random(Guid.NewGuid().GetHashCode()).Next(l.Length)].Trim();
byte[] byteData = Encoding.GetEncoding(codeType).GetBytes(postData);
request.Method = "POST";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.Timeout = 30 * 1000;
request.ReadWriteTimeout = 30 * 1000;
request.Proxy = null;
request.ContentType = "application/x-www-form-urlencoded; charset=" + codeType;
//if (BaseClass.SaLevel > 0)
{
//260306 采用GZip/deflate压缩
//request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br, zstd");
//request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
}
if (url.StartsWith("https://openapi.jinritemai.com/"))
{
request.Headers.Add("X-USE-BOE", "1");
request.Headers.Add("Origin-From", "djt_prod");
request.Headers.Add("djt_prod", "boe_time_sku");
}
if (!string.IsNullOrEmpty(contentType))
{
request.ContentType = contentType;
}
request.ContentLength = byteData.Length;
request.Referer = url;
request.CookieContainer = new CookieContainer();
request.AllowAutoRedirect = false;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(byteData, 0, byteData.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.GetEncoding(codeType));
return readStream.ReadToEnd().Trim();
}
catch (Exception e)
{
//{
// isError = true;
// goto reTry;
//}
Thread.Sleep(50);
return "";
}
}
public static int HexToInt(char h)
{
if ((h >= '0') && (h <= '9'))
{
return (h - '0');
}
if ((h >= 'a') && (h <= 'f'))
{
return ((h - 'a') + 10);
}
if ((h >= 'A') && (h <= 'F'))
{
return ((h - 'A') + 10);
}
return -1;
}
}
/// <summary>
/// class UrlDecoder
/// </summary>
class UrlDecoder
{
// Fields
private int _bufferSize;
private byte[] _byteBuffer;
private char[] _charBuffer;
private Encoding _encoding;
private int _numBytes;
private int _numChars;
// Methods
internal UrlDecoder(int bufferSize, Encoding encoding)
{
this._bufferSize = bufferSize;
this._encoding = encoding;
this._charBuffer = new char[bufferSize];
}
internal void AddByte(byte b)
{
if (this._byteBuffer == null)
{
this._byteBuffer = new byte[this._bufferSize];
}
this._byteBuffer[this._numBytes++] = b;
}
internal void AddChar(char ch)
{
if (this._numBytes > 0)
{
this.FlushBytes();
}
this._charBuffer[this._numChars++] = ch;
}
private void FlushBytes()
{
if (this._numBytes > 0)
{
this._numChars += this._encoding.GetChars(this._byteBuffer, 0, this._numBytes, this._charBuffer, this._numChars);
this._numBytes = 0;
}
}
internal string GetString()
{
if (this._numBytes > 0)
{
this.FlushBytes();
}
if (this._numChars > 0)
{
return new string(this._charBuffer, 0, this._numChars);
}
return string.Empty;
}
}
/// <summary>
/// 下载器
/// </summary>
public class WebClientx : WebClient
{
/// <summary>
/// 默认超时多少秒
/// </summary>
public int Timeout = 100;
/// <summary>
/// 允许自动重定向
/// </summary>
public bool AllowAutoRedirect = true;
public bool IsDelete = false;
private string OutIP = "";
/// <summary>
/// 证书列表
/// </summary>
public static List<Certificate> X509List = new List<Certificate>();
/// <summary>
/// 绑定IP
/// </summary>
/// <param name="outIp"></param>
public WebClientx(string outIp)
{
OutIP = outIp;
CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
}
public WebClientx()
{
}
/// <summary>
/// 重写
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
protected override WebRequest GetWebRequest(Uri address)
{
string s = address.ToString();
if (string.IsNullOrEmpty(s) || s.Length < 7 || !(s.Substring(0, 7).ToLower() == "http://" || s.Substring(0, 8).ToLower() == "https://"))
return null;
var request = (HttpWebRequest)base.GetWebRequest(address);
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
request.Timeout = 1000 * Timeout;
request.ReadWriteTimeout = 500 * Timeout;
request.AllowAutoRedirect = AllowAutoRedirect;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
if (IsDelete)
request.Method = "DELETE";
if (!string.IsNullOrEmpty(OutIP))
{
request.ServicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
{
servicePoint.MaxIdleTime = 20;
return new IPEndPoint(IPAddress.Parse(OutIP), 0);
};
}
if (request.RequestUri.Scheme == "https") //挂接验证服务端证书的回调
{
X509Certificate2 x509c = null;
for (int i = 0; i < X509List.Count; i++)
{
if (X509List[i].Domain.ToLower() == address.Host.ToLower())
{
x509c = X509List[i].X509;
break;
}
}
if (x509c == null)
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(RemoteCertificateValidationCallback);
try
{
X509Store _store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
_store.Open(OpenFlags.ReadWrite);
string findValue = Dns.GetHostName(); //获取本地主机名称作为证书查找的参数
X509Certificate2Collection _certsCollection =
_store.Certificates.Find(X509FindType.FindByIssuerName, findValue, false);
if (_certsCollection.Count > 0)
{
x509c = _certsCollection[0];
request.ClientCertificates.Add(x509c);
}
}
catch { }
}
}
return request;
}
/// <summary>
/// 获取证书
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public bool RemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
//if (sslPolicyErrors == SslPolicyErrors.None) {
// return true;
//}
//Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
//// Do not allow this client to communicate with unauthenticated servers.
//return false;
return true;
}
}
/// <summary>
/// 网站证书
/// </summary>
public class Certificate
{
/// <summary>
/// 域名
/// </summary>
public string Domain { get; set; }
/// <summary>
/// 证书
/// </summary>
public X509Certificate2 X509 { get; set; }
}
}