• 跨浏览器很棘手的问题探讨


        最经遇到一个很棘手的问题,写出来大家探讨一下。

        工作流系统中存在很多自定义的表单,由于是老系统,这些表单只能支持IE。现在做移动应用,需要将这些自定义的aspx表单展示在mobile safari浏览器中。

        这些自定义表单用了大量的htc、只支持ie的javascript。而现在的任务是需要将这些表单展示在mobile safari浏览器中。

        想了很多办法感觉都不好。昨天突然想到一个办法就是根据Url将表单转换成图片,然后展示到移动客户端。大致流程是:在服务端创建一个WebBrowser实例,在这个WebBrowser加载这个表单Url。由于WebBrowser内置的是IE内核,所以htc,javascript、css都能很好的运行,然后将通过ActiveX 将这个WebBrowser转换成图片。代码如下:

    IViewObject.cs

        [ComVisible(true), ComImport()]
        [GuidAttribute("0000010d-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IViewObject
        {
            [return: MarshalAs(UnmanagedType.I4)]
            [PreserveSig]
            int Draw(
                [MarshalAs(UnmanagedType.U4)] UInt32 dwDrawAspect,
                int lindex,
                IntPtr pvAspect,
                [In] IntPtr ptd,
                IntPtr hdcTargetDev,
                IntPtr hdcDraw,
                [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcBounds,
                [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcWBounds,
                IntPtr pfnContinue,
                [MarshalAs(UnmanagedType.U4)] UInt32 dwContinue);
            [PreserveSig]
            int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect,
               int lindex, IntPtr pvAspect, [In] IntPtr ptd,
                IntPtr hicTargetDev, [Out] IntPtr ppColorSet);
            [PreserveSig]
            int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect,
                            int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze);
            [PreserveSig]
            int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze);
            void SetAdvise([In, MarshalAs(UnmanagedType.U4)] int aspects,
              [In, MarshalAs(UnmanagedType.U4)] int advf,
              [In, MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink);
            void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects,
              [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf,
              [In, Out, MarshalAs(UnmanagedType.LPArray)] IAdviseSink[] pAdvSink);
        }
    

    HtmlCapture.cs

    publicclass HtmlCapture
    {
    private WebBrowser web;
    private Timer tready;
    private Rectangle screen;
    private Size? imgsize =null;

    //an event that triggers when the html document is captured
    publicdelegatevoid HtmlCaptureEvent(object sender,
    Uri url, Bitmap image);
    publicevent HtmlCaptureEvent HtmlImageCapture;

    //class constructor
    public HtmlCapture()
    {
    //initialise the webbrowser and the timer
    web =new WebBrowser();
    tready
    =new Timer();
    tready.Interval
    =2000;
    screen
    = Screen.PrimaryScreen.Bounds;
    //set the webbrowser width and hight
    web.Width = screen.Width;
    web.Height
    = screen.Height;
    //suppress script errors and hide scroll bars
    web.ScriptErrorsSuppressed =true;
    web.ScrollBarsEnabled
    =false;
    //attached events
    web.Navigating +=
    new WebBrowserNavigatingEventHandler(web_Navigating);
    web.DocumentCompleted
    +=new
    WebBrowserDocumentCompletedEventHandler(web_DocumentCompleted);
    tready.Tick
    +=new EventHandler(tready_Tick);
    }

    #region Public methods
    publicvoid Create(string url)
    {
    imgsize
    =null;
    web.Navigate(url);
    }

    publicvoid Create(string url, Size imgsz)
    {
    this.imgsize = imgsz;
    web.Navigate(url);
    }
    #endregion

    #region Events
    void web_DocumentCompleted(object sender,
    WebBrowserDocumentCompletedEventArgs e)
    {
    //start the timer
    tready.Start();
    // string s = web.Document.GetElementById("").InnerHtml;


    }

    void web_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
    //stop the timer
    tready.Stop();
    }



    void tready_Tick(object sender, EventArgs e)
    {
    //stop the timer
    tready.Stop();
    //get the size of the document's body
    Rectangle body = web.Document.Body.ScrollRectangle;

    //check if the document width/height is greater than screen width/height
    Rectangle docRectangle =new Rectangle()
    {
    Location
    =new Point(0, 0),
    Size
    =new Size(body.Width > screen.Width ? body.Width : screen.Width,
    body.Height
    > screen.Height ? body.Height : screen.Height)
    };
    //set the width and height of the WebBrowser object
    web.Width = docRectangle.Width;
    web.Height
    = docRectangle.Height;

    //if the imgsize is null, the size of the image will
    //be the same as the size of webbrowser object
    //otherwise set the image size to imgsize
    Rectangle imgRectangle;
    if (imgsize ==null)
    imgRectangle
    = docRectangle;
    else
    imgRectangle
    =new Rectangle()
    {
    Location
    =new Point(0, 0),
    Size
    = imgsize.Value
    };
    //create a bitmap object
    Bitmap bitmap =new Bitmap(imgRectangle.Width, imgRectangle.Height);
    //get the viewobject of the WebBrowser


    IViewObject ivo
    = web.Document.DomDocument as IViewObject;
    ivo.ToString();
    using (Graphics g = Graphics.FromImage(bitmap))
    {
    //get the handle to the device context and draw
    IntPtr hdc = g.GetHdc();
    ivo.Draw(
    1, -1, IntPtr.Zero, IntPtr.Zero,
    IntPtr.Zero, hdc,
    ref imgRectangle,
    ref docRectangle, IntPtr.Zero, 0);
    g.ReleaseHdc(hdc);
    }
    //invoke the HtmlImageCapture event
    HtmlImageCapture(this, web.Url, bitmap);
    }
    #endregion
    }
    }

    下面我们使用上面代码可以截图工作流表单的图片了:

           void hc_HtmlImageCapture(object sender, Uri url, Bitmap image)
            {
               image.Save("C:/test.bmp");
            }
            private void button1_Click(object sender, EventArgs e)
            {
             HtmlCapture hc = new HtmlCapture();
             hc.HtmlImageCapture += new HtmlCapture.HtmlCaptureEvent(hc_HtmlImageCapture);
             hc.Create("http://10.5.23.117:8011/Recipe1.aspx");
        
           }
    

    这样效果和PC端展示一样。

    截取百度快照:

    获取的图片:

    尽管展示和pc端一样,但是图片存在的问题主要有:

    1、不支持复制粘贴

    2、不支持多标签页的切换(移动端不需要支持表单编辑功能)

    3、不支持超链接点击

    总结:由于WebBrowser支持htc、已经写好的javascript代码,而js和htc做了不少业务逻辑处理,所以在服务端使用WebBrowser去处理表单的思路是正确的。但是进一步如何解决上面的三个问题。需要进一步探讨。在不大量修改之前存在的工作流表单的前提下,如果你有更好的想法,期待你的告诉我。

    附:根据url抓取图片代码



    (全文完)


    以下为广告部分

    您部署的HTTPS网站安全吗?

    如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

    SSL检测评估

    快速了解HTTPS网站安全情况。

    安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

    SSL证书工具

    安装部署SSL证书变得更方便。

    SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

    SSL漏洞检测

    让服务器远离SSL证书漏洞侵扰

    TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

    作者:朱祁林 出处:http://zhuqil.cnblogs.com 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。  
  • 相关阅读:
    react文本溢出hover气泡显示全部文本——JS判断文本溢出
    ecosystem.config
    git删除中间某次提交
    HTML5 新元素
    HTML5存储
    简述LVS(Linux虚拟服务器)
    简述线程池
    网络协议基础
    JVM常用性能检测工具
    线程间的“通信”方法
  • 原文地址:https://www.cnblogs.com/zhuqil/p/2143502.html
Copyright © 2020-2023  润新知