Google Docs viewer returning 204 responses, no longer working, alternatives?

后端 未结 7 1907
执念已碎
执念已碎 2020-12-08 01:01

UPDATE 2016-11-16 9:53am EST

It appears many people are still seeing 204 responses even though Google has claimed to have \"fixed\" the problem. Wh

相关标签:
7条回答
  • 2020-12-08 01:32

    I was using the Google Viewer as a copy viewer for our internal management system, we generally only upload PDF's and image files, so as a all-in-one solution is was brilliant, worked across the board (mobile, desktop etc). However with it becoming increasingly unreliable, I got creative.

    My solution was to generate and save a JPG version of the PDF using imagick if it was viewed after being uploaded. Rather than batching all of the uploaded PDFs, they are only converted when they are accessed.

    My reasoning for that is:

    1. I have a very small user pool so file types are easily managed
    2. The likelihood of every PDF needing to be viewed again after upload is almost nil, so it's only created when needed for reporting purposes.
    3. I need a reliable way of viewing the file via mobile devices. iOS and Android do not play well with in browser PDF viewers and everyone knows how much hassle PDF's are on an iOS device (iBooks anyone?)

    Once the file has been viewed and a jpg version of the pdf created, it is used in place of the PDF whenever it is viewed by a user. Not pretty but certainly works, I admit there is an element of doubling up however I do not have any storage limitations. The original file is also not modified in anyway so it serves as a tertiary remote backup too. This is not by design, but a happy coincidence.

    Feel free to use the code below if it's useful to you. There are probably more elegant ways to do this, but for my purposes and users it's fine.

                $_thumbnail = 'files/thumbnails/'.$_section.'/'.$_fileName.'.jpg';
    
                if (!file_exists($_thumbnail)) {
    
                        $_file = 'files/'.$_section.'/'.$_fileName;
    
                        $imagePreview = new imagick();
                        $imagePreview->setResolution(300, 300);
                        $imagePreview->readimage($_file);
                        $imagePreview->setImageFormat( "jpg" );
                        $imagePreview->writeImage('files/thumbnails/'.$_section.'/'.$_fileName.'.jpg');
    
                        echo '<img src="/files/thumbnails/'.$_section.'/'.$_fileName.'.jpg" width="100%"/>';
    
                } else {
                        echo '<img src="/files/thumbnails/'.$_section.'/'.$_fileName.'.jpg" width="100%"/>';
    
                }
    
    0 讨论(0)
  • 2020-12-08 01:38

    I solved this problem as follows. If google viewer is not loaded, make iframe restart.

    function reloadIFrame() {
    var iframe = document.getElementById("iFrame");
      console.log(frame.contentDocument.URL); //work control
      if(iframe.contentDocument.URL == "about:blank"){
        iframe.src =  iframe.src;
      }
    }
    var timerId = setInterval("reloadIFrame();", 2000);
    
    $( document ).ready(function() {
        $('#menuiFrame').on('load', function() {
            clearInterval(timerId);
            console.log("Finally Loaded"); //work control
        });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <iframe id="iFrame" src="https://docs.google.com/gview?url=http:exemple.pdf?entryPoint=projectimage&id=1bef4781-5eb5-60b0-8f0b-5426c9877ebe&type=apoll_Web_Project_Files&embedded=true" style="width:718px; height:700px;" frameborder="0"></iframe>

    0 讨论(0)
  • 2020-12-08 01:38

    I was able to get this to work with Тетяна Волошка's answer, however I had to remove the if statement because

    This

    iframe.contentDocument.URL == "about:blank"
    

    caused

    DOMException: Blocked a frame with origin from accessing a cross-origin frame.
    

    I'm not quite sure why this fixed it for me. Perhaps the 2 second delay allowed everything else on my page to load and remove any conflict for the embedded pdf to load, but how else could i get the content document without a the cross-origin issue?

    0 讨论(0)
  • 2020-12-08 01:38

    Thought I'd share this solution here also, as the answers above won't work efficiently for a large document: The load event will not fire for a few seconds after the iFrame has started loading, so you might end up with an endless loop. A better solution is to also check for the size of the body of the iFrame.

    0 讨论(0)
  • 2020-12-08 01:48

    I run a service that also relies on embedding the Google Doc Viewer and I have also encountered this issue. I could not find any other comparable service (free or otherwise).

    I have come up with a 'hack' that can help you get away with using the Google Doc Viewer. It does require JQuery though. What I do is keep refreshing the iframe every 2 seconds until it finally loads correctly. I also cover the iframe with a loading gif to hide the constant refreshing. My code:

    <style>
    .holds-the-iframe {
        background:url(/img/loading.gif) center center no-repeat;
    }
    </style>
    
    <div class="holds-the-iframe">
          <iframe id="iframeID" name="iframeID" src="https://docs.google.com/viewerng/viewer?url=www.example.com&embedded=true"></iframe>
    </div>
    
    <script>
    function reloadIFrame() {
        document.getElementById("ifm").src=document.getElementById("iframeID").src;
    }
    
    timerId = setInterval("reloadIFrame();", 2000);
    
    $( document ).ready(function() {
        $('#iframeID').on('load', function() {
            clearInterval(timerId);
            console.log("Finally Loaded");
        });
    });
    </script>
    
    0 讨论(0)
  • 2020-12-08 01:52

    A simple solution/hack with Reactjs, though can be easily implemented to any other library/vanilla.

    Used with a basic concept : tries to load - if onload accomplish, clear interval, otherwise try to load again every 3 sec. works perfectly

    (I've edited my own code it so it will contain minimum code, so not tested)

    var React = require('react');

    export default class IframeGoogleDocs extends React.Component {
        constructor(props) {
            super();
            this.bindActions();
        }
        bindActions() {
            this.updateIframeSrc = this.updateIframeSrc.bind(this);
            this.iframeLoaded = this.iframeLoaded.bind(this);
        }
        iframeLoaded() {
            clearInterval(this.iframeTimeoutId);
        }
        getIframeLink() {
            return `https://docs.google.com/gview?url=${this.props.url}`; // no need for this if thats not dynamic
        }
        updateIframeSrc() {
            this.refs.iframe.src = this.getIframeLink();
        }
        componentDidMount() {
            this.iframeTimeoutId = setInterval(
                this.updateIframeSrc, 1000 * 3
            );
        }
        render() {
            return (
                <iframe onLoad={this.iframeLoaded} onError={this.updateIframeSrc} ref="iframe" src={this.getIframeLink()}></iframe>
            );
        }
    }
    
    0 讨论(0)
提交回复
热议问题