[译]HTML过滤器禁止各种弹出窗口
By robot-v1.0
本文链接 https://www.kyfws.com/applications/html-filter-to-ban-pop-ups-of-all-kinds-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 7 分钟阅读 - 3354 个词 阅读量 0[译]HTML过滤器禁止各种弹出窗口
原文地址:https://www.codeproject.com/Articles/3028/HTML-filter-to-ban-pop-ups-of-all-kinds
原文作者:Stephane Rodriguez.
译文由本站 robot-v1.0 翻译
前言
Free tool to close pop up windows
免费工具关闭弹出窗口
过滤出HTML内容(Filtering out HTML content)
介绍(Introduction)
HTML筛选器是我受够了各种弹出式窗口后编写的工具.(HTML Filter is a tool I wrote after being fed up with pop up windows of all kinds.)
当然,应用HTML过滤来关闭自动弹出的窗口是一个非常有效的应用程序.但这不是唯一的一种,它实际上给这项技术带来了更多的兴趣.(Applying HTML filtering to close automatically pop up windows, is of course a quite effective application. But that’s not the only one, which actually brings a lot more interest to the technique.)
HTML筛选器?(HTML Filter?)
我花了很多时间尝试使用诸如此类的"外部工具"自动关闭弹出窗口(I have spent much time trying to close pop ups automatically by using “external tools” such as this) 一(one) .外部工具会定期根据已知的禁止的窗口名称词典检查打开的窗口.只要您(. External tools check out open windows on a regular time basis against a known dictionary of banned window names. This works fine, as long as you’re)*快乐(happy)*由于广告名称一直在变化,因此被迫每隔一天添加一次新条目.(with being forced to add new entries every other day since ad names keep changing all the time.)
因此,我不得不找出一种更内部的方式.我发现,在尝试与IE一起使用几次之后,订阅事件有很多限制和奇怪的事情发生,无论出于什么原因,有时这些事件根本不会触发.我以为我必须找到更激进的东西,而不必再与我使用的导航器相结合了.(So I had to find out a more internal way of doing it. I found that, after trying to work along with IE a couple of times already, there were many limits and weird things happening there with subscribed events, which for any reason sometimes don’t trigger at all. I thought I had to find something more radical, and less coupled with the navigator I was using.)
我终于成功地提出了一个代理过滤器,这是一个系统托盘工具,一旦配置,它就会向每个HTTP数据包来回发送,并有独特的机会查看HTML内容本身.(I finally successfully came up with a proxy filter, a systray tool which, once configured, sends back and forth, every HTTP packet, with the unique opportunity of seeing the HTML content itself.)
这个机会很好.应用预定义的过滤规则可以例如删除各种讨厌的JavaScript,这些JavaScript以在屏幕上弹出弹出窗口而闻名.(This opportunity is great. Applying predefined filtering rules allows for instance to remove all kinds of nasty JavaScript known for bringing pop ups on screen, you know that nasty) window.open (url, "xyz", ...)
东西.(things.)
配置工具(Configuring the tool)
安装后,它将开始在默认的8010端口上监听.如果您已经在使用此端口,请对其进行更改,这就是对话框的用途.当然,您必须让导航器知道您正在那里聆听,所以我们打开(Once installed, it starts listening on the default 8010 port. If you are already using this port, change it, that’s what the dialog box is for. Of course, you must let the navigator know that you are listening there, so let’s open the)Windows控制面板(Windows control panel),然后双击(, then double-click on)互联网选项(Internet Options).在里面(. In the)连接数(Connections)标签,只需编辑(tab, just edit the)代理设定(Proxy Settings), 点击(, click on)高级(Advanced),然后输入(, and type)**127.0.0.1(127.0.0.1)**在…前面(in front of)要使用的HTTP代理地址(HTTP Proxy address to use)-服务器字段,然后键入(- Server field, and type)**8010(8010)**在里面(in the)*港口(Port)*领域.按"应用".好的,您完成了.您可以像以前一样浏览网页,而无需进行任何重大更改(至少在表面上).(field. Press “Apply”. Ok, you’re done. You can go back and surf the web as you previously did, without notable changes (at least on surface).)
如果您使用的是Netscape甚至Opera,只需使用类似的步骤更改代理设置.对于Netscape,请进入(If you are using Netscape or even Opera, just change the proxy settings using a similar procedure. For Netscape, go in the)编辑/首选项(Edit / Preferences),然后在(, then in)高级/代理(Advanced / Proxy),然后编辑(, and edit the)*HTTP代理(HTTP Proxy)*领域.(field.)
过滤器会自动激活,这意味着过滤通过它的HTML内容,并应用规则.源代码提供了过滤器(The filter is automatically activated, which means the HTML content going through it is filtered, and rules are applied. The source code provided filters) window.open
陈述,用伪造的陈述代替(statements, replacing them with faked) //ndow.open
您可以自行决定是否在(and it is up to you to add any other relevant rules in the) CHtmlFilterRules
类的实现.要禁用过滤,只需右键单击系统托盘并选择选项.(class implementation. To disable filtering, just right-click in the systray and choose the option.)
我还希望该工具不会减慢冲浪体验.通过使用简单的套接字而不是诸如此类的MFC包装器可以实现此目标.(I also wanted the tool not to slow down the surfing experience. This goal is achieved by using simple sockets instead of MFC wrappers such like) CAsyncSocket
(这反过来使((which in turn mess a lot around with the) _afxThreadSockState
一团糟).(mess).)
技术细节(Technical details)
该工具充当代理服务器.它基本上实现了双线程套接字线.该代码基于Nish的(This tool acts as a proxy server. It basically implements a double-threaded socket line. The code is based on Nish’s) 弹出代理服务器(pop proxy server) .运作方式如下所示:(. How things work is depicted below :)
html过滤器的工作原理(How the html filter works)
主类声明如下:(The main class is declared as below :)
class CHttpProxyMT
{
// Members
//
protected:
SOCKET m_HttpServerSocket;
HANDLE m_ServerThread;
int m_port;
BOOL bRunning; // Flag that's set if the proxy is running
// Constructor
//
public:
CHttpProxyMT();
virtual ~CHttpProxyMT();
// Methods
//
public :
// This starts the multi-threaded HTTP proxy server
BOOL StartProxy(int port);
BOOL IsRunning();
void StopProxy();
int GetProxyPort();
int GetNBConnections();
void EnableFiltering(BOOL bEnable=TRUE);
private:
// The thread that listens for connections
static DWORD ServerThread(void *arg); // thread callback
DWORD MServerThread();
static DWORD ClientThread(DWORD arg); // thread callback
void StartClientThread(SOCKET sock);
static void StartDataThread(void *parm); // thread callback
static DWORD DataThread(void *parm); // thread callback
};
struct socket_pair
{
socket_pair(SOCKET s1, SOCKET s2, BOOL bIsServerResponse)
{
srcsock = s1;
dstsock = s2;
m_bIsServerResponse = bIsServerResponse;
n = 0;
}
SOCKET srcsock;
SOCKET dstsock;
BOOL m_bIsServerResponse;
int n;
char buff[16384+1];
};
有趣的是,当您开始使用线程时,突然间,一切都变得混乱了.的确,每个变量都有被多个线程同时访问的潜在危险,这使得实际上编写任何代码变得更加困难.我最终将套接字对实例与每个线程相关联,并且基本上在每行代码中都引用了该对象,因此确保我是线程安全的.但是很糟糕,在此特定时刻需要的是一个简单的框架,用于将变量和映射附加到正在运行的线程.仅仅因为在Win32下线程回调是一个(What’s funny is when you start working with threads, suddenly, everything comes so messed up. Indeed, every variable is under the potential fire of being accessed by several threads at the same time, making it just harder to code practically anything. I ended up associating a socket pair instance to each thread and basically referring to this object in every line of code, so to make sure I was sort of thread-safe. But it sucks, what one needs at this particular moment is an easy framework to attach variables and maps to the running thread. It becomes so amazing just because under Win32 the thread callback is a) static
(读((read)全球(global))函数,因此每个线程都可以使用和重用该函数.() function, thus used and reused by each thread.)
最后,在将服务器响应发送回客户端时,我得到了这样的代码:(In the end, I have code like this when it comes to sending server responses back to the client :)
DWORD CHttpProxyMT::DataThread(void *parm)
{
socket_pair* spair = (socket_pair*) parm;
// recv bytes from server and send
//them back to the client, once filtered
while( (spair->n=recv(spair->srcsock, spair->buff, 16384, 0))>0 )
{
spair->buff[spair->n] = 0;
if (g_bFilteringEnabled && spair->m_bIsServerResponse)
{
CHtmlFilterRules filter( spair->buff,spair->n );
filter.ApplyRules();
}
send(spair->dstsock, spair->buff, spair->n, 0);
}
...
}
应用规则取决于您打算做什么.基本上,我想注释掉弹出窗口的JavaScript代码,但实际上,该概念可以用于许多其他应用程序.使用过滤器禁止弹出窗口的结果是,在HTML中,打开弹出窗口的方式是通过(Applying rules is up to what you intend to do. Basically I wanted to comment out pop up window JavaScript code, but virtually the concept can be used for many other applications. Using filtering to forbid pop up windows comes as a consequence to the fact that, in HTML, the way to open pop up windows is through the) window.open
JavaScript命令.注释掉这条线使其成为KO,这就是我们想要的.这是它的代码:(JavaScript command. Commenting out this line makes it KO, which is what we are looking for. Here is the code for it :)
CHtmlFilterRules::CHtmlFilterRules(char *buffer, int nLength)
{
m_cpBuffer = buffer;
m_nLength = nLength;
}
BOOL CHtmlFilterRules::ApplyRules()
{
// we are already done!
if (!m_cpBuffer || !m_nLength) return FALSE;
// copy the buffer, in order to be able to
//compare the strings regardless of the case
char *buf = new char[m_nLength+1];
if (!buf) return FALSE;
memcpy(buf, m_cpBuffer, m_nLength);
buf[m_nLength]=0; // force EOL to allow str C-routines to work
strlwr(buf); // convert to lowercase (CPU time here)
char *szPattern = buf;
char *szFirstByte = buf;
while ( (szPattern=strstr(szPattern,"window.open"))!=NULL )
{
// replace window.open by //ndow.open
// so the javascript code doesn't create any annoying popup
m_cpBuffer[szPattern-szFirstByte+0] = '/';
m_cpBuffer[szPattern-szFirstByte+1] = '/';
szPattern++;
}
delete [] buf;
return TRUE;
}
代码清单:(同时提供了VC6和VC7工作区)(Code listing: (both VC6 and VC7 workspaces provided))
- HtmlFilterRules.cpp(HtmlFilterRules.cpp):HTML过滤器(: HTML filter)
- HttpProxyMT.cpp(HttpProxyMT.cpp):基于Nish的PopProxyMT多线程POP代理服务器(: based on Nish’s PopProxyMT multi-threaded POP proxy server)
- htmlfilterdlg.cpp(htmlfilterdlg.cpp):端口配置,菜单命令(: port configuration, menu commands)
- htmlfilter.cpp(htmlfilter.cpp):赢应用(: Win app)
- TrayNot.cpp(TrayNot.cpp):简单的系统托盘实现(: simple systray implementation)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
VC7.0 C++ VC6 WinXP Windows Win2K MFC Visual-Studio Dev 新闻 翻译