HTML代码过滤技术

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

HTML代码过滤技术

郑恒

 

参考资料:MSDN的《Pluggable Protocols Overview

参考示例:MSDN提供的

       http://support.microsoft.com/default.aspx?scid=kb;EN-US;q260840#appliesto

       另一示例是用Delphi写的:http://www.guicode.com/scr/mimefilter.zip

 

 

 

       要实现HTML代码过滤必需注册一个或多个MIME过滤器(Pluggable MIME Filter)。

MIME过滤器是一个COM对象,必需实现IInternetProtocolSinkIInternetProtocol接口。MIME过滤器可以注册成临时或者永久的,如果同时注册多个临时的MIME过滤器,那么后注册的对象先被调用!

 

       要如何注册一个MIME过滤器?要注册一个永久MIME过滤器,你必需在注册表

HKEY_CLASSES_ROOT/PROTOCOLS/Filter键下添加一个子键,子键的名称是你要

注册的MIME类型,在添加的子键下必需有一个名为CLSID的字符串值,值的内容就是你

提供的COM对象的CLSID。该键的默认值可以是关于你的对象的简单描述。如果你用ATL

了开发,你可以在对象的RGS文件中添加如下内容:

HKCR

{

         NoRemove PROTOCOLS

         {

                   NoRemove Filter

                   {

                            ForceRemove 'text/html' = s 'XMLMimeFilter MIME Filter Sample'

                            {

                                     val CLSID = s '{53B95211-7D77-11D2-9F80-00104B107C96}'

                            }

                   }

         }

}

上面的代码来自文章开头提到的示例。’XMLMimeFilter MIME Filter Sample’

'{53B95211-7D77-11D2-9F80-00104B107C96}'都要换成你自已的!

 

       如果要注册临时MIME过滤器,就要通过IInternetSession接口(取消注册也

使用该接口),下面提供的注册一个临时过滤器的代码:

CComPtr<IInternetSession> m_spSession ;

CComPtr<IClassFactory>    m_spClassFactoryMime ;

hr = ::CoGetClassObject( CLSID_MimeFilter, CLSCTX_SERVER,

                                                NULL, IID_IClassFactory,

                             (void**)&m_spClassFactoryMime );

if( hr == S_OK )

{

         if( ::CoInternetGetSession( 0, &m_spSession, 0) ==S_OK )

         {

                   m_spSession->RegisterMimeFilter(m_spClassFactoryMime,

                                               CLSID_MimeFilter,                                                                                                                                       L"text/html" );

         }

}

这里的CLSID_MimeFilter就是你的对象的CLSID

 

 

MIME的类型有许多种,要了解这些信息可以查看MSDN的附录

MIME Type Detection in Internet Explorer 4.0》,但实际的类型要比这里列的多得多。

要了解你的电脑注册的MIME类型,可以查看注册表的[HKEY_CLASSES_ROOT/MIME/

Database/Content Type]键。也可以通过调用FindMimeFromData函数来得到文件的对应MIME

类型,下面的代码示例了得到JS文件的MIME类型:

LPWSTR pwzMimeOut ;

FindMimeFromData( NULL , L"time.js" , 0 , 0 , 0 , 0 , &pwzMimeOut , 0 );

得到的MIME类型是:application/x-javascript

       一般情况下,要过滤HMTL页面,可以注册text/html类型。你也可以根据实际情况

通过调用RegisterMimeFilter注册多个不同的MIME过滤器。

 

 

 

       注册一个临时或永久的MIME过滤器后,接下来的工作就是实现MIME过滤器对象

在实现之前,先看一下《Pluggable Protocols Overview》一文中关于MIME过滤器与WEB

处理器(transaction handler,即urlmon.dll)之间接口的调用的描述(注:urlmon.dll内部实现了IInternetProtocolIInternetProtocolSink接口):

 

1、  WEB处理器调用MIME过滤器的IInternetProtocolRoot::Start方法(IInternetProtocol

IInternetProtocolRoot派生);

2、  WEB处理器先后调用MIME过滤器的IInternetProtocolSink::ReportProgress

IInternetProtocolSink::ReportData方法;

3、  MIME过滤器调用WEB处理器的IInternetProtocol::Read方法;

4、  MIME过滤器调用WEB处理器的IInternetProtocolSink::ReportData方法;

5、  WEB处理器调用MIME过滤器的IInternetProtoco::Read方法;

 

因此,要实现MIME过滤器,有几个重要的方法:

1IInternetProtocolRoot::Start方法:

HRESULT Start(

    [in] LPCWSTR szUrl,

    [in] IInternetProtocolSink *pOIProtSink,

    [in] IInternetBindInfo *pOIBindInfo,

    [in] DWORD grfPI,

    [in] DWORD dwReserved

);

作为MIME过滤对象,szUrl传入的是MIME的类型(如果是name space handlers对象,

则该参数为一个即将下载或解析的URL)。若是你想得到URL,可以通过pOIBindInfo

口得到,下面是示例:

       LPOLESTR pwzUrl ;           

       ULONG uElFetched ;

       pIBindInfo->GetBindString( BINDSTRING_URL , &pwzUrl , 1 , &uElFetched )

 

pOIProtSink是由urlmon.dll提供的IInternetProtocolSink接口,因为在后面的处理过程中,需要调用到该接口,所以要将它保存;

grfPI是一个枚举变量,必需包含PI_FILTER_MODE标志,表示该对象运行在filter模式中。

dwReserved是一个指向PROTOCOLFILTERDATA结构的指针,该结构的pProtocol成员是由urlmon.dll提供的IInternetProtocol接口,因为在后面的处理过程中需要调用到该接口,所以要将它保存。实际上该接口也可以通过pOIProtSink参数调用QueryInterface得到,同样PROTOCOLFILTERDATA结构的pProtocolSinkpOIProtSink都是指向同一个接口。

 

       Start方法中,我们必需做的实际上只是保存urlmon.dll提供的IInternetProtocolSink

IInternetProtocol接口。

 

 

 

2IInternetProtocolSink::ReportProgress方法:

HRESULT ReportProgress(

    [in] ULONG ulStatusCode,

    [in] LPCWSTR szStatusText )

作为MIME过滤器,ulStatusCode一般都是BINDSTATUS_CACHEFILENAMEAVAILABLE , 当

ulStatusCode为BINDSTATUS_CACHEFILENAMEAVAILABLE时,szStatusText为临时缓存文件

的路径名称,但有一些网页并不写到缓存里,所以szStatusText可能为空字符串。

 

 

3、IInternetProtocolSink::ReportData方法:

HRESULT ReportData(
    [in] DWORD grfBSCF,
    [in] ULONG ulProgress,
    [in] ULONG ulProgressMax
);

IE下载文件过程中或下载完毕时会调用MIME过滤器的ReportData方法,ulProgressMax

为文件总是数据量,ulProgress为下载进度,理论上当文件全部下载完后,ulProgress应

等于ulProgressMax(实际上,当网页文件不是很大时,即使ulProgress不等于ulProgressMax时,文件也可能全部下载下来),还有一个反应文件下载情况的参数是grfBSCF。有时,ReportData方法会被Web处理器调用多次。

    ReportData是过滤网页内容或修改网页内容比较合适的地方。在此地,可以将网页内容通过调用Read保存到自已的缓存或流中并做适当的处理(注意检查字符的编码)。

最后,别忘了调用Web处理器的IInternetProtocolSink::ReportData方法,向它汇报数据下载的情况。Web处理器得到此通知后,就会调用MIME过滤器的IInternetProtocol::Read,此时,你就可以将修改后的数据交给WEB处理器。

    下面的代码示例了如何在ReportData中调用Web处理器的Read预先保存数据:

// m_spIncomingProt是在Start中保存的Web处理器的IInternetProtocol接口

// m_spStm 是IStream 指针,用来缓存数据

BYTE buffer[ SIZE_BUFFER ] ;

DWORD cbRead ;

do

{              

    cbRead = 0 ;       

    hr = m_spIncomingProt->Read( buffer , SIZE_BUFFER , &cbRead ) ;

   

    if( cbRead > 0 ) **A 处

    {

        if( m_spStm->Write( buffer , cbRead , NULL ) == S_OK )

        {

            m_cbTotal += cbRead ;

        }

}

}while ( hr == S_OK );

 

Read成功取得数据一般只返回S_OK或S_FALSE ,返回S_OK表示还有数据,而S_FALSE

表示数据已读取完毕,因此循环的条件设为 hr==S_OK。那A处的条件判断为什么不是

if( hr == S_OK || hr == S_FALSE ) 呢, 因为我发现某些情况下,Read可能返回其

它值,但仍然有成功读取一部分数据出来,数据的大小就是cbRead指定的值。如果将

那部分数据遗落,网页将无法正常解析!那这样会不会导致因读取失败而将一些无用的

数据保存到缓存中?至少目前还没碰到过。

 

 

4、IInternetProtocol::Read方法

    该方法由WEB处理器调用来取得浏览器要解析的数据。在上一方法ReportData中

我们已经将所有数据缓存到流中,因此,这里只需将流中的数据返回给WEB处理器。

下面的代码示例了Read中的简单处理:

    if( m_spStm->Read( pv , cb , pcbRead ) == S_OK )

    {

        if(  *pcbRead == cb )

        {

            return S_OK ;

        }

        else

            return S_FALSE ;

    }

    千万注意,在数据已读取完毕时要返回S_FALSE , 不然可能导致Read被无穷循环调用。

    处理完这几个方法后,基本是大功造成,其它一些方法处理十分简单,可以参考上面

提到的例子。           

            2005-7-27

注:本文出处http://www.guicode.com/blog%5CMime_Filter.htm

HTML网页实现】这段代码是一个简单的用户过滤功能的网页实现 这段代码实现了一个基本的实时用户过滤功能,用户可以通过搜索框输入名字或位置来过滤用户列表。代码的结构清晰,使用了现代HTML、CSS和JavaScript技术,包括flexbox布局、异步请求和事件监听等。 阅读详情

相关推荐

HTML交互式数据筛选项目实战

在现代Web应用中,条件筛选是一个必不可少的功能。它允许用户根据特定的标准对数据进行排序、筛选和搜索。理解其工作原理和最佳实践对于前端开发人员至关重要,因为它直接影响到用户的交互体验。

weixin_30978239的博客 795

vue开发项目时返回的图片路径只有文件名没有全路径,怎样拼接全路径,富文本编辑器返回的数据咋过滤里面的html标签或者样式或者格式

拼接图片全路径和正则匹配

AKindofo的博客 1109

HTML代码过滤工具

用于过滤HTML代码的工具,小巧,而且听实用的

彻底监视Internet Explorer的下载

Internet Explorer下载文件的终极过滤                                                               ———— 彻底监视Internet Explorer的下载你是否想过类似下面的一些问题?l         如何过滤IE中的flash?l         如何过滤在网页中嵌入email的尼姆达病毒?l         如

kuelite的专栏 1303

IE浏览器 自定义地址协议的实现

关键字:IE插件,shell接口编程,自定义IE协议,VC2003ATL实现COM 浏览QQ空间的时候发现,只要在IE地址中输入象一下这种形式的地址,tencent://Message/?Uin=251464630&amp;websiteName=qzone.qq...

weiyinchao88 483

CoInternetGetSession

This function creates a session that allows temporary asynchronous pluggable protocols to be implemented and returns the IInternetSession interface of the session. 这个函数创建一个session对象,以允许同步可插拔协议的实现,同

hellochenlian的专栏 1063

html数据自动过滤对象,HTML代码过滤技术

参考资料:MSDN的《Pluggable Protocols Overview》参考示例:MSDN提供的要实现HTML代码过滤必需注册一个或多个MIME过滤器(Pluggable MIME Filter)。MIME过滤器是一个COM对象,必需实现IInternetProtocolSink和IInternetProtocol接口。MIME过滤器可以注册成临时或者永久的,如果同时注册多个临时的MIME...

weixin_42294133的博客 550

通过Mime filter技术对网页源码进行过滤,本文部分摘自《HTML代码过滤技术

要实现HTML代码过滤必需注册一个或多个MIME过滤器(Pluggable MIME Filter)。MIME过滤器是一个COM对象,必需实现IInternetProtocolSink和IInternetProtocol接口。       在实现MIME过滤器对象之前,先看一下《Pluggable Protocols Overview》一文中关于MIME过滤器与WEB处理器(transacti

ljmscsq的专栏 2878

编辑器粘贴过滤技术详解

  http://www.cnblogs.com/tonyqus/archive/2010/05/29/html_editor_paste_filter.html 在线Html编辑器粘贴过滤技术详解(一) http://www.cnblogs.com/tonyqus/archive/2010/06/03/html_editor_paste_filter2.html 在线Html编辑器粘贴过...

阿蔡的专栏 523

网页源码过滤

 本例通过Mime filter技术对网页源码进行过滤,本文部分摘自《HTML代码过滤技术》       要实现HTML代码过滤必需注册一个或多个MIME过滤器(Pluggable MIME Filter)。MIME过滤器是一个COM对象,必需实现IInternetProtocolSink和IInternetProtocol接口。       在实现MIME过滤器对象之前,先看一下

hbrr224的专栏 1362

图像平滑过滤_HTML图像过滤方法简介

图像平滑过滤As I head towards another NMPD showcase, a number of my students are finishing up portfolios that feature photographs, art and design works with rollover effects: changing an image from greyscal...

cungui5726的博客 221

ASP教程:过滤HTML代码并截取

正常ASP中对录入内容的过滤仅仅是对左尖括号()的HTML源码的替换,以在页面中显示为左右尖括号,而不是将尖括号作为HTML标签执行了。当然这应该是属于正常过滤手法,而还有一种过滤方法则是将一对尖括号及尖括号中的所有字符均替换不显示,作为过滤HTML标签的最终极手法,但该方法对于内容中必须描述有关尖括号内容则是过滤过头了(比如本文起始所引用的相关尖括号符号均将看不见“”也将看不见)。不过,

南三方---网站设计开发录 876

下拉选择框的选项过滤

使用:filterValue="1,3",filterValue="3" <dict:select dictTypeId="DICT_VIMTECH_CERTTYPE" defultValue="3" filterOp="in" filter="true" filterValue="3" onchange="changeCodeType(this.value)" cssClass="ea...

weixin_34361881的博客 164

如何过滤php中危险的HTML代码

用php过滤html里可能被利用来引入外部危险内容的代码。有些时候,需要让用户提交html内容,以便丰富用户发布的信息,当然,有些可能造成显示页面布局混乱的代码也在过滤范围内。 以下是引用片段: #用户发布的html,过滤危险代码 function uh($str) { $farr = array( "/s+/", //过滤多余的空白 "/&lt;(/?)(script|i?fr...

weixin_34111790的博客 177
上一篇: 2005仲秋(忆)
下一篇: VB分布式应用程序开发随记---绑定技术概述
lion_wing
博客等级 码龄24年 30粉丝 45原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值