制作一个“;Web代理”-循序渐进
本文关键字:Web 代理 循序渐进 一个 | 更新日期: 2023-09-27 18:26:45
有什么方法可以在您的页面中显示另一个页面吗?我不能使用框架,因为框架会直接打开那个页面,我想复制整个页面并将其保存到新文件中,然后向用户显示我的新文件。我认为最好使用简单的URL加密,因为我不喜欢显示真实的页面地址。例如,我想使用以下URL而不是yahoo.com:www.myDomain.com/Open.aspx?url=zipp_dpn。。。我知道如何读取、加密和解密URL,但我的问题是我不知道如何将该页面复制到新页面以及如何显示。
编辑:我不知道如何开始研究,甚至我不知道我应该寻找什么。这就是我在这里向专家提问的原因。我需要一个关键词来开始研究!
听起来像是在尝试设置代理。
您可以执行以下操作:
-
使用HTTP处理程序侦听请求。这可以是MVC控制器、web表单(ASPX)、
IHttpHandler
的实例,甚至是原始TCP服务器。 -
使用加密的URL来确定目标网站。
-
从您的网站向其他网站提出请求。在.Net中有多种方法可以做到这一点,包括
HttpClient
类。 -
将响应转换为字符串。
-
(可选)解析内容中的链接以指向您的代理网站地址,而不是真实地址。
-
将字符串作为响应的主体返回给调用者。据他们的浏览器所知,这就是他们请求的页面。
免责声明:虽然代理是常用的,但在不同的URL下呈现他人的内容可能会产生潜在的影响(超出我的非法律知识和建议)。此外,绕过过滤后的内容可能还有其他(可能是严重的)后果。即使修改了URL,代理内容仍然可能触发过滤器。
好吧,我终于开始创建一个web代理了。
我决定在这里解释我的工作有两个原因:1) 适合所有想开始类似项目的人。2) 这些代码的大部分都是从Stack页面复制的,我刚刚收集了它们。)
我需要专家来纠正我的错误,并帮助我继续前进。
以下是我所做的:
ASP(Default.aspx):
我放了一个名为"txtURL"的文本框,按用户输入网址。
我放置了一个名为"btnRun"的按钮来开始处理。
目前,这些组件就足够了!
C#:
单击"btnRun",页面重定向到:"www.domain.com/default.aspx?URL=(xxx)"-xxx将被一个函数加密的网页地址所取代。
这是btnRun_Click:的代码
protected void btnRun_Click(object sender, EventArgs e)
{
if (txtURL.Text.Length == 0) return;
if (!(txtURL.Text.ToLower().StartsWith("http://") || txtURL.Text.ToLower().StartsWith("https://")))
txtURL.Text = "http://" + txtURL.Text;
try
{
Response.Redirect("Default.aspx?URL=(" + Encrypt(txtURL.Text, mainKey) + ")", false);
}
catch (Exception ex)
{
ShowPopUpMsg(ex.Message);
}
稍后我将解释"Encrypt"answers"ShowPopUpMsg"函数。
点击"btnRun",此页面将被刷新,加密的URL将包含在地址中。
现在,在"Page_Load"中,我们应该读取加密的URL(也是检测回发的条件):
protected void Page_Load(object sender, EventArgs e)
{
string url = Regex.Match(HttpContext.Current.Request.Url.AbsoluteUri, @"'(([^)]*)')").Groups[1].Value;
if (url.Length == 0 || Page.IsPostBack) return;
从现在起,每个代码都会一个接一个地添加到"Page_Load"中。
解密URL并读取远程网页源代码:
try
{
txtURL.Text = Server.UrlDecode(Decrypt(url, mainKey));
string TheUrl = txtURL.Text;
string response = GetHtmlPage(TheUrl);
稍后我将解释"解密"answers"GetHtmlPage"。
现在,我们有了"response"中的源代码。
下一步是在此源代码中查找链接。链接的开头是"href="xxx"",xxx就是链接。我们必须通过代理将它们替换为我们的链接:
response = response.Replace("href =", "href=");
response = response.Replace("href'n=", "href=");
response = response.Replace("href't=", "href=");
HtmlWeb hw = new HtmlWeb();
HtmlDocument doc = hw.Load(txtURL.Text);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
{
char[] c = { ' ', ''"' };
string s = link.OuterHtml;
int from = s.IndexOf("href=");
int to = SearchString(s, from, ''"');
s = s.Substring(from + 5, to - from - 5);
s.TrimStart(c);
if (s.StartsWith("'"")) s = s.Remove(0, 1);
"SearchString"是一个返回"href"的右引号的函数。我稍后再解释。
有两种链接:
指向另一个域名的链接。这些链接以"http://"或"https://"开头。我们会找到它们并替换地址:
string corrected = "href='"" + "Default.aspx?URL=(" + Encrypt(s, mainKey) + ")" + "'""; if ((s.ToLower().StartsWith("http://") || s.ToLower().StartsWith("https://"))) response = response.Replace("href='"" + s + "'"", corrected);
引用当前域名的链接。这些链接以"/"开头。要替换它们,我们应该首先找到域名,然后找到整个地址:
else { var uri = new Uri(txtURL.Text); string domain = uri.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped); corrected = "href='"" + "Default.aspx?URL=("; if (txtURL.Text.ToLower().StartsWith("http://")) corrected += Encrypt("http://" + domain + s, mainKey); if (txtURL.Text.ToLower().StartsWith("https://")) corrected += Encrypt("https://" + domain + s, mainKey); corrected += ")" + "'""; response = response.Replace("href='"" + s + "'"", corrected); }
现在,一切都完成了(参考我目前的知识),我们应该显示带有新链接的页面,并完成"page_Load":
}
Response.Write(response);
}
catch (Exception ex)
{
ShowPopUpMsg(ex.Message);
}
}
在字符串中搜索的函数:
private int SearchString(string mainString, int startLocation, char charToFind)
{
if (startLocation < 0) return -1;
bool next = false;
for (int i = startLocation; i < mainString.Length; i++)
if (mainString.Substring(i, 1) == charToFind.ToString() && next)
return i;
else
{
if (mainString.Substring(i, 1) == charToFind.ToString()) next = true;
continue;
}
return -1;
}
读取源代码的功能:
private string GetHtmlPage(string URL)
{
String strResult;
WebResponse objResponse;
WebRequest objRequest = HttpWebRequest.Create(URL);
objResponse = objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
sr.Close();
}
return strResult;
}
显示弹出消息的功能:
private void ShowPopUpMsg(string msg)
{
StringBuilder sb = new StringBuilder();
sb.Append("alert('");
sb.Append(msg.Replace("'n", "''n").Replace("'r", "").Replace("'", "'''"));
sb.Append("');");
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "showalert", sb.ToString(), true);
}
解密字符串的函数:
private string Decrypt(string s, string key)
{
try
{
byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(s);
System.Configuration.AppSettingsReader settingsReader = new System.Configuration.AppSettingsReader();
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray);
}
catch { return null; }
}
加密字符串的函数:
private string Encrypt(string s, string key)
{
try
{
byte[] keyArray; byte[] encryptArray = UTF8Encoding.UTF8.GetBytes(s);
System.Configuration.AppSettingsReader SettingReader = new System.Configuration.AppSettingsReader();
MD5CryptoServiceProvider Hashmd5 = new MD5CryptoServiceProvider();
keyArray = Hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); Hashmd5.Clear();
TripleDESCryptoServiceProvider Tdes = new TripleDESCryptoServiceProvider();
Tdes.Key = keyArray; Tdes.Mode = CipherMode.ECB; Tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform Ctransform = Tdes.CreateEncryptor();
byte[] resultarray = Ctransform.TransformFinalBlock(encryptArray, 0, encryptArray.Length);
Tdes.Clear(); return Convert.ToBase64String(resultarray, 0, resultarray.Length);
}
catch { return null; }
}