skip to Main Content

Im trying to implement 3d secure, I have html code and I can open it in iframe as srcDoc (html string).And I want to access the form inside the iframe by using useref and close the iframe if form is posted.But I always got this error "react-dom.development.js:20724 Uncaught DOMException: Failed to read a named property ‘document’ from ‘Window’: Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame." (by the way ,I enable cross origin in config ,and try –disable-web-security in chrome but still same error…
Any help is appricated,thx.

     const ref = useRef();
    // this is html document ,base64
    const bss="PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8dGl0bGU+aXl6aWNvIE1vY2sgM0QtU2VjdXJlIFByb2Nlc3NpbmcgUGFnZTwvdGl0bGU+CjwvaGVhZD4KPGJvZHk+Cjxmb3JtIGlkPSJpeXppY28tM2RzLWZvcm0iIGFjdGlvbj0iaHR0cHM6Ly9zYW5kYm94LWFwaS5peXppcGF5LmNvbS9wYXltZW50L21vY2svaW5pdDNkcyIgbWV0aG9kPSJwb3N0Ij4KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im9yZGVySWQiIHZhbHVlPSJtb2NrNDYtNjg3NjU1ODAwODI2MjM5NWl5emlvcmQiPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYmluIiB2YWx1ZT0iNTUyNjA4Ij4KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InN1Y2Nlc3NVcmwiIHZhbHVlPSJodHRwczovL3NhbmRib3gtYXBpLml5emlwYXkuY29tL3BheW1lbnQvaXl6aXBvcy9jYWxsYmFjazNkcy9zdWNjZXNzLzI3Ij4KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImZhaWx1cmVVcmwiIHZhbHVlPSJodHRwczovL3NhbmRib3gtYXBpLml5emlwYXkuY29tL3BheW1lbnQvaXl6aXBvcy9jYWxsYmFjazNkcy9mYWlsdXJlLzI3Ij4KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImNvbmZpcm1hdGlvblVybCIgdmFsdWU9Imh0dHBzOi8vc2FuZGJveC1hcGkuaXl6aXBheS5jb20vcGF5bWVudC9tb2NrL2NvbmZpcm0zZHMiPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iUGFSZXEiIHZhbHVlPSJjYWIxNjA0YS02MWJiLTQ0NGQtOGExNS1kZDZmMzhjZGRiNjMiPgo8L2Zvcm0+CjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpeXppY28tM2RzLWZvcm0iKS5zdWJtaXQoKTsKPC9zY3JpcHQ+CjwvYm9keT4KPC9odG1sPg=";

const [htmlbase, setHtmlbase] = useState('');

useEffect(() => {
setHtmlbase(decode(bss2));
}, []);
     
    
            const buttonOnclick = () => { 
    // this attempts always null ,cant access the document in iframe
                   const frame = ref.current;
                         if (frame.current?.contentDocument) // FF Chrome
                            ifrDoc = frame.current?.contentDocument;
                        else if ( frame.current?.contentWindow ) // IE
                            ifrDoc = frame.current?.contentWindow.document;
        
          };
          <iframe 
            width="500px"  id="myIframe" 
            height="320px"
            srcDoc={htmlbase}  
        sandbox="allow-forms allow-modals allow-same-origin allow-scripts allow-popups allow-top-navigation"
         onLoad={handleFrameElement}
            position="relative"  ref={ref}/>

3

Answers


  1. As you know, that Next.JS is a modern web framework which can work in both server and client side. To access the iframe and window make sure that your page is run on client side not in server side. Because the default Next.JS 14 AppRouter is run on server side, not in client side.

    In the top of your page add 'use client' to make sure that you’re using client-side rendering.
    But if you want to access it inside server side rendering, make sure that window is exist before attempting any DOM manipulation. For example

    import { useRouter } from 'next/router';
    
    function MyPage() {
      const router = useRouter();
    
      if (typeof window !== 'undefined') {
        // if window exist in client
        console.log('window is exist');
      } else {
        // if window doesnt exist in server side
        console.log('window doesnt exist');
      }
    
      return <div>My Page</div>;
    }
    
    Login or Signup to reply.
  2. That error message means you don’t currently have access to the content of the iframe. This can happen because either it has not actually loaded yet, or because the browser sees it coming from a different domain to the parent page.

    Decoding your base64 string gives.

    <!doctype html>
    <html lang="en">
    <head>
        <title>iyzico Mock 3D-Secure Processing Page</title>
    </head>
    <body>
    <form id="iyzico-3ds-form" action="https://sandbox-api.iyzipay.com/payment/mock/init3ds" method="post">
        <input type="hidden" name="orderId" value="mock46-6876558008262395iyziord">
        <input type="hidden" name="bin" value="552608">
        <input type="hidden" name="successUrl" value="https://sandbox-api.iyzipay.com/payment/iyzipos/callback3ds/success/27">
        <input type="hidden" name="failureUrl" value="https://sandbox-api.iyzipay.com/payment/iyzipos/callback3ds/failure/27">
        <input type="hidden" name="confirmationUrl" value="https://sandbox-api.iyzipay.com/payment/mock/confirm3ds">
        <input type="hidden" name="PaReq" value="cab1604a-61bb-444d-8a15-dd6f38cddb63">
    </form>
    <script type="text/javascript">
        document.getElementById("iyzico-3ds-form").submit();
    </script>
    </body>
    </html>
    

    This is redirecting to another site (I’m guessing sandbox-api isn’t the site of the main app), so once the form is submitted, the iframe is then cross domain and I am guessing you don’t want to close it before it has submitted.

    The best you can do, if you don’t want to change the three response URLs to you own site, is wait for the onLoad event to fire a second time on the iframe. This will indicate that the form has completed submission and the response page has loaded.

    If for some reason that is the same domain as the parent, then my next suggestions would be to remove sandbox and then not use srcdoc, as it creates it’s own set of issues in my experience.

    Login or Signup to reply.
  3. After writing the other answer, I noticed your buttonOnclick function.

    const frame = ref.current;
    if (frame.current?.contentDocument) // FF Chrome
      ifrDoc = frame.current?.contentDocument;
    else if ( frame.current?.contentWindow ) // IE
      ifrDoc = frame.current?.contentWindow.document;
    

    Your referencing current twice, shouldn’t this just be

    const buttonOnclick = () => { 
      ifrDoc = ref.current?.contentDocument
    }
    

    You don’t need the rest of this code, contentDocument goes back to IE8.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search