none
[IE编程]MIME过滤导致flash被阻止如何解决? RRS feed

  • 问题

  • 环境:vs2005 C# winform XPsp2 IE8 
    测试网页:中国雅虎首页

    成功地给WebBrowser安装了MIME过滤,添加的过滤类型是"text/html"。出现一个问题:网页里显示flash的JS代码失效了。

    以yahoo首页为例:
    <script charset="gbk" src="http://p.tanx.com/ex?i=mm_17230573_2278684_8962768"></script>

    开始我以为是自己在获取网页源码时出了问题,但我使用IE把网页保存为纯html后再打开,flash也不能显示。经查是IE的安全机置所造成。可采用如下解决办法:

    在<html>之前添加:"<!-- saved from url=(0013)about:internet -->"

    加上这行代码后,本地的html文件可以显示出flash了。于是我便在MIME过滤器里,把返给IE的网页源码里也加上了这行代码。不料还是显示不出flash

    不仅是MIME协议,别一个扩展协议:NameSpace也存在这个问题。我使用自己的保存代码将网页数据存入内存后,再利用NameSpace从内存加载网页。虽然在协议里我接到了falsh数据请求而且我也将内存中的flash数据提交给了IE,但是网页中却显示不出falsh来。当时百思不得其解,而今日这问题表明这似乎是IE的一个bug?


    还请大虾们提出宝贵意见,谢谢。

    2011年6月20日 7:23

答案

  • 请记住,Flash 是基于 ActiveX 的方式运行的,如果您的程序是在本地使用了 IE 内核,如 msdocvw.dll,进行网页显示,那么,就必须启用 IE 的本地 Intranet 功能,才能在本地运行类似于 Flash 的 ActiveX。

    其实这个与 MIME 并没有直接关系,MIME 是告诉 IE,哪一种类型的文件用什么样的程序打开。比如 swf 的 MIME Type 是类似于 Shockware/FlashObject 的东西,只要这个 swf 可以成功被下载,那就没太大关系。

    您可以在测试时,先把 IE 的安全级别降下来,比如允许所有 ActiveX 代码,测试完后,弄清楚了到底是 MIME Filter 的问题还是 IE 设置问题,再恢复安全性设置。


    Mark Zhou
    • 已标记为答案 Aspen VJ 2011年6月29日 1:33
    2011年6月20日 9:39
  • 您使用了 MIME Filter 后,运行您的程序,打开 yahoo.com.cn,用调试窗口显示一下它的 HTML Source,这个 Source 正常吗?检查一下有没有 <object ... />.
    Mark Zhou
    • 已标记为答案 Aspen VJ 2011年6月29日 1:33
    2011年6月22日 7:40

全部回复

  • 请记住,Flash 是基于 ActiveX 的方式运行的,如果您的程序是在本地使用了 IE 内核,如 msdocvw.dll,进行网页显示,那么,就必须启用 IE 的本地 Intranet 功能,才能在本地运行类似于 Flash 的 ActiveX。

    其实这个与 MIME 并没有直接关系,MIME 是告诉 IE,哪一种类型的文件用什么样的程序打开。比如 swf 的 MIME Type 是类似于 Shockware/FlashObject 的东西,只要这个 swf 可以成功被下载,那就没太大关系。

    您可以在测试时,先把 IE 的安全级别降下来,比如允许所有 ActiveX 代码,测试完后,弄清楚了到底是 MIME Filter 的问题还是 IE 设置问题,再恢复安全性设置。


    Mark Zhou
    • 已标记为答案 Aspen VJ 2011年6月29日 1:33
    2011年6月20日 9:39
  • 楼上朋友您好:

    如果您的程序是在本地使用了 IE 内核,如 msdocvw.dll,

     --我使用的是C#自带的WebBrowser控件

    另外对于MIME,我目前对它的理解就是:IE(或者说是我进程内的WebBrowser控件)把下载到的数据首先提交给我,我处理后再返给IE。借此可以实现网页内容的过滤。比如去除掉一些不合规则的文字。

    我是通过IInternetSession。RegisterMimeFilter来注册进程内有效的MIME。

    而实现协议的DLL也是用C#制作的。并使用C#方式进行了注册。

    经测试,在默认安全级别下sohu、新浪这些网页在我的MIME下,我进程内的WebBrowser里能够显示完整内容,flash也全部显示。

    而中国yahoo,即便我将IE安全级别调到了最低(最低貌似就是"中"),“充许活动内容在我计算机上的文件中运行”也被我勾选了。但依然显出不出flash(我偏爱yahoo,测试程序也拿yahoo首页进行)。

    这样看起来似乎只是yahoo一个特列。但目前主流Browser基本上都实现了网页内容过滤(主要是为了去广告)。我认为它们应该也是利用了MIME技术。但人家的yahoo就可以完整显示啊。

    虽然它们都是VC开发的,不过我相信即然VC能做到的,C#为什么不可以呢?还请大虾们继续指教教啊!

    下面贴一部分我的MIME实现相关代码:

     [ComVisible(true)]
    
     [Guid("1c470f4b-0486-4558-80c7-ad08d652a465"), ClassInterface(ClassInterfaceType.AutoDispatch)]
    
     public class MimeHandler : IInternetProtocol, IInternetProtocolRoot, IInternetProtocolSink
    
     {
    
      #region 常量
    
      const int S_OK = 0x00000000;
    
      const int S_FALSE = 0x00000001;
    
      const int E_FAIL = unchecked((int)0x80004005);
    
      const int E_POINTER = unchecked((int)0x80004005);
    
      const int INET_E_ERROR_FIRST = unchecked((int)0x800C0002);
    
      const int INET_E_INVALID_URL = unchecked((int)0x800C0002);
    
      const int INET_E_NO_SESSION = unchecked((int)0x800C0003);
    
      const int INET_E_CANNOT_CONNECT = unchecked((int)0x800C0004);
    
      const int INET_E_RESOURCE_NOT_FOUND = unchecked((int)0x800C0005);
    
      const int INET_E_OBJECT_NOT_FOUND = unchecked((int)0x800C0006);
    
      const int INET_E_DATA_NOT_AVAILABLE = unchecked((int)0x800C0007);
    
      const int INET_E_DOWNLOAD_FAILURE = unchecked((int)0x800C0008);
    
      const int INET_E_AUTHENTICATION_REQUIRED = unchecked((int)0x800C0009);
    
      const int INET_E_NO_VALID_MEDIA = unchecked((int)0x800C000A);
    
      const int INET_E_CONNECTION_TIMEOUT = unchecked((int)0x800C000B);
    
      const int INET_E_INVALID_REQUEST = unchecked((int)0x800C000C);
    
      const int INET_E_UNKNOWN_PROTOCOL = unchecked((int)0x800C000D);
    
      const int INET_E_SECURITY_PROBLEM = unchecked((int)0x800C000E);
    
      const int INET_E_CANNOT_LOAD_DATA = unchecked((int)0x800C000F);
    
      const int INET_E_CANNOT_INSTANTIATE_OBJECT = unchecked((int)0x800C0010);
    
      const int INET_E_USE_DEFAULT_PROTOCOLHANDLER = unchecked((int)0x800C0011);
    
      const int INET_E_QUERYOPTION_UNKNOWN = unchecked((int)0x800C0013);
    
      const int INET_E_REDIRECT_FAILED = unchecked((int)0x800C0014);
    
      const int INET_E_REDIRECT_TO_DIR = unchecked((int)0x800C0015);
    
      const int INET_E_CANNOT_LOCK_REQUEST = unchecked((int)0x800C0016);
    
      #endregion
    
    
    
      #region 全局对象
    
      private string cacheFileName = "";
    
    
    
      private string url;
    
    
    
      private MemoryStream dataStream = new MemoryStream();
    
    
    
      private IInternetProtocol urlMonProtocol;
    
    
    
      private IInternetProtocolSink urlMonProtocolSink;
    
    
    
      private byte[] buffer = null;
    
      private uint written = 0;
    
    
    
      private long totalSize = 0;
    
    
    
      protected MemoryStream Stream = new MemoryStream(0x8000);
    
    
    
      protected byte[] StreamBuffer = new byte[0x8000];
    
    
    
      private string MimeType = "";
    
      private string char_set = "";
    
      #endregion
    
    
    
      //System.IO.File.AppendAllText("C:\\buzou.txt", "Read" + "\r\n");
    
    
    
      public MimeHandler()
    
      {
    
    
    
      } 
    
    
    
      /*MIME type 
    
      text/html; charset=GB2312
    
      text/css
    
      application/x-javascript(试验性质)
    
      application/javascript
    
      text/javascript(已过时) */
    
    
    
      public void Start(string szURL, IInternetProtocolSink Sink,
    
       IInternetBindInfo pOIBindInfo, uint grfPI, uint dwReserved)
    
      {
    
       //作为MIME过滤对象,szUrl传入的是MIME的类型
    
       //(如果是name space handlers对象,则该参数为一个即将下载或解析的URL)。
    
       //在Start方法中,我们必需做的实际上只是保存urlmon.dll提供的IInternetProtocolSink
    
       //和IInternetProtocol接口。
    
    
    
       MimeType = szURL;
    
    
    
       urlMonProtocol = (IInternetProtocol)Sink; 
    
       urlMonProtocolSink = Sink; 
    
    
    
       //获取网址
    
       uint Fetched = 0;
    
       const int BINDSTRING_URL = 14;
    
       pOIBindInfo.GetBindString(BINDSTRING_URL, ref url, 1, ref Fetched);
    
    
    
       throw new COMException("", S_OK);
    
      }
    
    
    
       
    
      public void ReportProgress(uint ulStatusCode, string szStatusText)
    
      {
    
       //作为MIME过滤器,ulStatusCode一般都是BINDSTATUS_CACHEFILENAMEAVAILABLE , 
    
       //当ulStatusCode为BINDSTATUS_CACHEFILENAM EAVAILABLE时,szStatusText为临时
    
       //缓存文件的路径名称,但有一些网页并不写到缓存里,所以szStatusText可能为空字符串。
    
    
    
       uint bindStatus = Convert.ToUInt32(BINDSTATUS.BINDSTATUS_CACHEFILENAMEAVAILABLE);
    
    
    
       if (ulStatusCode == bindStatus)
    
       {
    
        cacheFileName = szStatusText;
    
       }
    
    
    
       urlMonProtocolSink.ReportProgress(ulStatusCode, szStatusText);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
    
    
      public void ReportData(BSCF grfBSCF, uint ulProgress, uint ulProgressMax)
    
      {
    
       UInt32 resultOfRead;
    
       //获取数据 - 处理数据 -交回数据
    
    
    
       //IE下载文件过程中或下载完毕时会调用MIME过滤器的ReportData方法,ulProgressMax为文件总是数据量,
    
       //ulProgress为下载进度,理论上当文件全部下载完后,ulProgress应等于ulProgressMax(实际上,当网页
    
       //文件不是很大时,即使ulProgress不等于ulProgressMax时,文件也可能全部下载下来),还有一个反应文
    
       //件下载情况的参数是grfBSCF。有时,ReportData方法会被Web处理器调用多次。 
    
       //ReportData是过滤网页内容或修改网页内容比较合适的地方。在此地,可以将网页内容通过调用Read保存
    
       //到自已的缓存或流中并做适当的处理(注意检查字符的编码)。
    
       //最后,别忘了调用Web处理器的IInternetProtocolSink::ReportData方法,向它汇报数据下载的情况。
    
       //Web处理器得到此通知后,就会调用MIME过滤器的IInternetProtocol::Read,此时,你就可以将修改后的
    
       //数据交给WEB处理器。
    
    
    
    
    
       dataStream = new MemoryStream();//接收数据
    
    
    
       do
    
       { //while result == S_OK there is still data 
    
    
    
        byte[] readBuffer = new byte[1024];
    
    
    
        uint totalRead;
    
    
    
    
    
        int size = Marshal.SizeOf(readBuffer[0]) * readBuffer.Length;
    
    
    
    
    
        IntPtr unmanagedPointer = Marshal.AllocHGlobal(size);//win32地址
    
    
    
        Marshal.Copy(readBuffer, 0, unmanagedPointer, readBuffer.Length);//初始化win32内存
    
    
    
        // Call unmanaged code 
    
    
    
        //这里并不知道有多少数据需要下载,给IE个内存空间让其往里放数据,根据返回值判断是否下载完毕。
    
        resultOfRead = urlMonProtocol.Read(unmanagedPointer, Convert.ToUInt32(readBuffer.Length), out totalRead);
    
    
    
    
    
        byte[] receiveBuffer = new byte[1024];
    
    
    
    
    
        Marshal.Copy(unmanagedPointer, receiveBuffer, 0, 1024);
    
    
    
        dataStream.Write(receiveBuffer, 0, Convert.ToInt32(totalRead));
    
    
    
        //free memory 
    
    
    
        Marshal.FreeHGlobal(unmanagedPointer);
    
    
    
       } //while (resultOfRead == HRESULT.S_OK);
    
       while ((resultOfRead != S_FALSE) &&
    
        (resultOfRead != INET_E_DOWNLOAD_FAILURE) && (resultOfRead != INET_E_DATA_NOT_AVAILABLE));
    
    
    
    
    
       if (resultOfRead == HRESULT.S_FALSE)//如果数据接收完毕
    
       {
    
        //all data recieved 
    
        dataStream.Flush();
    
    
    
        totalSize = dataStream.Length;
    
    
    
        //INSERT MANIPULATION OF DATA! 
    
    
    
        HandleData();//处理数据
    
    
    
        
    
        urlMonProtocolSink.ReportData(//交回数据
    
         BSCF.BSCF_FIRSTDATANOTIFICATION | 
    
         BSCF.BSCF_LASTDATANOTIFICATION | 
    
         BSCF.BSCF_DATAFULLYAVAILABLE, Convert.ToUInt32(totalSize), Convert.ToUInt32(totalSize));
    
    
    
        urlMonProtocolSink.ReportResult(Convert.ToInt32(HRESULT.S_OK), HRESULT.S_OK, null);
    
       }
    
       throw new COMException("", S_OK);
    
      } 
    
    
    
     
    
      //IE读取你交回的数据
    
      public UInt32 Read(System.IntPtr pv, uint cb, out uint pcbRead)
    
      { 
    
       pcbRead = 0;
    
    
    
       if (written < totalSize)
    
       {
    
        if (totalSize - written <= cb)
    
        {
    
         Marshal.Copy(buffer, (int)written, pv, (int)(totalSize - written));
    
         pcbRead = (uint)(totalSize - written);
    
         written += (uint)(totalSize - written);
    
         return (UInt32)S_FALSE; 
    
        }
    
        else
    
        {
    
         Marshal.Copy(buffer, (int)written, pv, (int)cb);
    
         written += cb;
    
         pcbRead = cb;
    
         return (UInt32)S_OK; 
    
        }
    
       }
    
       else
    
       { return (UInt32)S_FALSE; }
    
      }
    
    
    
    
    
      public void Resume()
    
      {
    
       urlMonProtocol.Resume();
    
       throw new COMException("", unchecked((int)0x80004001));
    
      }
    
    
    
    
    
      public void Terminate(uint dwOptions)
    
      {
    
       urlMonProtocol.Terminate(dwOptions);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
      public void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out _ULARGE_INTEGER plibNewPosition)
    
      {
    
       urlMonProtocol.Seek(dlibMove, dwOrigin, out plibNewPosition);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
    
    
      public void LockRequest(uint dwOptions)
    
      {
    
       urlMonProtocol.LockRequest(dwOptions);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
    
    
      public void UnlockRequest()
    
      {
    
       urlMonProtocol.UnlockRequest();
    
       throw new COMException("", S_OK);
    
      }
    
    
    
    
    
      public void Abort(int hrReason, uint dwOptions)
    
      {
    
       urlMonProtocol.Abort(hrReason, dwOptions);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
      public void Suspend()
    
      {
    
       urlMonProtocol.Suspend();
    
    
    
       throw new COMException("", unchecked((int)0x80004001));
    
      }
    
    
    
      public void Continue(ref _tagPROTOCOLDATA pProtocolData)
    
      {
    
       urlMonProtocol.Continue(ref pProtocolData);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
      public void Switch(ref _tagPROTOCOLDATA pProtocolData)
    
      {
    
       urlMonProtocolSink.Switch(ref pProtocolData);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
      public void ReportResult(int hrResult, uint dwError, string szResult)
    
      {
    
       urlMonProtocolSink.ReportResult(hrResult, dwError, szResult);
    
       throw new COMException("", S_OK);
    
      }
    
    
    
      #region 辅助函数
    
      public static IHttpNegotiate GetHttpNegotiate(IInternetProtocolSink Sink)
    
      { 
    
    
    
        if ((Sink is IServiceProvider) == false) 
    
    
    
         throw new Exception("Error ProtocolSink does not support IServiceProvider."); 
    
     
    
        IServiceProvider Provider = (IServiceProvider) Sink; 
    
    
    
        object obj_Negotiate = new object(); 
    
    
    
        Provider.QueryService(ref Guids.IID_IHttpNegotiate, ref Guids.IID_IHttpNegotiate, out obj_Negotiate); 
    
    
    
        return (IHttpNegotiate) obj_Negotiate; 
    
       } 
    
    
    
     
    
      public static BINDINFO GetBindInfo(IInternetBindInfo pOIBindInfo)
    
      { 
    
       BINDINFO BindInfo = new BINDINFO(); 
    
    
    
       BindInfo.cbSize = (UInt32) Marshal.SizeOf(typeof (BINDINFO)); 
    
    
    
       UInt32 AsyncFlag; 
    
    
    
       pOIBindInfo.GetBindInfo(out AsyncFlag, ref BindInfo); 
    
    
    
       return BindInfo; 
    
      } 
    
    
    
    
    
      private void HandleData()
    
      {
    
       buffer = new byte[(int)dataStream.Length];
    
       dataStream.Seek(0, SeekOrigin.Begin);
    
       dataStream.Read(buffer, 0, buffer.Length);
    
       written = 0;
    
       totalSize = buffer.Length;
    
    
    
       string content = BytesToString(buffer, out char_set);
    
    
    
       if (this.MimeType.IndexOf("javascript",StringComparison.OrdinalIgnoreCase) != -1)
    
       {
    
    
    
       }
    
       else if (this.MimeType.IndexOf("html", StringComparison.OrdinalIgnoreCase) != -1)
    
       {
    
        //<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
        Regex reg_first = new Regex("<!DOCTYPE[^>]+?>",RegexOptions.IgnoreCase);
    
        Match m = reg_first.Match(content);
    
        if(m.Success)
    
        {
    
         int head = content.IndexOf(m.Value,StringComparison.OrdinalIgnoreCase);
    
         if (head != -1)
    
         {
    
          string l = url.Length.ToString();
    
          while (l.Length < 4)
    
          {
    
           l = "0" + l;
    
          }
    
    
    
          l = "(" + l + ")" + url;
    
    
    
          content = content.Substring(0, head + m.Value.Length) +
    
           //"\r\n<!-- saved from url=(0013)about:internet -->\r\n" +
    
           "\r\n <!-- saved from url=" + l + " --> " +
    
           content.Substring(head + m.Value.Length);
    
    
    
          content = content.Replace(m.Value,
    
           "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\">");
    
    
    
          System.IO.File.WriteAllText("C:\\html.txt", content, Encoding.GetEncoding(char_set));
    
         }
    
        }
    
    
    
        /*
    
        int head = content.IndexOf("<head>",StringComparison.OrdinalIgnoreCase);
    
        if(head != -1)
    
        {
    
         string l = url.Length.ToString();
    
         while(l.Length < 4)
    
         {
    
          l = "0" + l;
    
         }
    
    
    
         l = "(" + l + ")" + url ;
    
    
    
         content = content.Substring(0, head + "<head>".Length) +
    
          //"\r\n<!-- saved from url=(0013)about:internet -->\r\n" +
    
          "\r\n<!-- saved from url=" + l + " -->" +
    
          content.Substring(head + "<head>".Length);
    
    
    
         System.IO.File.AppendAllText("C:\\html.txt", content, Encoding.GetEncoding(char_set));
    
        }*/
    
       }
    
    
    
       byte[] data = StringToBytes(content, char_set);
    
       /*
    
       string output = "";
    
       byte[] data = GetUTF8StringData(content, out output);*/
    
       dataStream = new MemoryStream(data);
    
    
    
       buffer = new byte[(int)dataStream.Length];
    
       dataStream.Seek(0, SeekOrigin.Begin);
    
       dataStream.Read(buffer, 0, buffer.Length);
    
       written = 0;
    
       totalSize = buffer.Length;
    
      }
    
    
    
      private string BytesToString(byte[] data,out string charSet)
    
      {
    
       charSet = "";
    
       string sHtml = Encoding.Default.GetString(data);
    
       string CharSet = "";
    
    
    
       Regex rg = new Regex("<meta.+?charset=(?<name>.*?)\".*?>", RegexOptions.IgnoreCase);
    
       Match m = rg.Match(sHtml);
    
    
    
       if(m.Success)
    
       {
    
        CharSet = m.Groups["name"].Value;
    
        charSet = CharSet;
    
       }
    
    
    
       if (CharSet.Length > 0)
    
       {
    
        sHtml = Encoding.GetEncoding(CharSet).GetString(data);
    
       }
    
    
    
       return sHtml;
    
      }
    
    
    
      private byte[] StringToBytes(string text,string charSet)
    
      {
    
       if (charSet.Length > 0)
    
       { return Encoding.GetEncoding(charSet).GetBytes(text); }
    
       else
    
       { return Encoding.Default.GetBytes(text); }
    
      }
    
    
    
      public static byte[] GetUTF8StringData(string input, out string output)
    
      {
    
       Regex reg_charset = new Regex("<meta.+?charset=(?<name>.*?)\".*?>", RegexOptions.IgnoreCase);
    
       Regex reg_title = new Regex("<title>.+</title>", RegexOptions.IgnoreCase);
    
    
    
       Match m_title = reg_title.Match(input);
    
       Match m_charset = reg_charset.Match(input);
    
    
    
       if (m_charset.Success)
    
       {
    
        string CS = m_charset.Groups["name"].Value;
    
    
    
        /*
    
        string strBig5 = sHtml;
    
        byte[] aby = Encoding.UTF8.GetBytes(strBig5);
    
        string f = Tools.GenerateCheckCodeNum(8);
    
        FileStream fs = new FileStream(string.Format("C:\\{0:s}.txt", f), FileMode.Create);
    
        fs.Write(aby, 0, aby.Length);
    
        fs.Close();*/
    
    
    
        string newInput = input.Replace(m_charset.Value, m_charset.Value.Replace(CS, "UTF-8"));
    
        if (m_title.Success && m_title.Index < m_charset.Index)
    
        {
    
         newInput = newInput.Replace(m_title.Value, "_ASDJDHGSGDJ_");
    
         newInput = newInput.Replace(m_charset.Value, m_title.Value);
    
         newInput = newInput.Replace("_ASDJDHGSGDJ_", m_charset.Value);
    
        }
    
    
    
        byte[] temp = Encoding.UTF8.GetBytes(newInput);
    
    
    
        if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF)
    
        {
    
         byte[] temp2 = new byte[temp.Length + 3];
    
         Buffer.BlockCopy(temp, 0, temp2, 3, temp.Length);
    
         temp2[0] = 0xEF;
    
         temp2[1] = 0xBB;
    
         temp2[2] = 0xBF;
    
    
    
         output = System.Text.Encoding.UTF8.GetString(temp2);
    
         return temp2;
    
        }
    
        else
    
        {
    
         output = System.Text.Encoding.UTF8.GetString(temp);
    
         return temp;
    
        }
    
       }
    
       else
    
       {
    
        output = input;
    
        return System.Text.Encoding.Default.GetBytes(input);
    
       }
    
      }//end fun
    
      #endregion
    
     } 
    
    

     

     

     

     

     

     


    2011年6月20日 10:52
  • 自己顶一下
    2011年6月21日 12:09
  • 您使用了 MIME Filter 后,运行您的程序,打开 yahoo.com.cn,用调试窗口显示一下它的 HTML Source,这个 Source 正常吗?检查一下有没有 <object ... />.
    Mark Zhou
    • 已标记为答案 Aspen VJ 2011年6月29日 1:33
    2011年6月22日 7:40