如何在弹窗中加载Spotify授权登录页面?

问题描述 投票:0回答:1

我正在尝试在新的弹出窗口中打开 Spotify 的登录页面,以便用户可以授予我的应用程序访问其 Spotify 数据的权限。我正在向 Spotify 发出服务器端请求,然后根据身份验证流程将接收 HTML 从服务器发送到客户端。

当我尝试打开弹出窗口时,除了三个加载点之外什么也没有看到,问题就出现了。我从 Spotify 收到的代码正在工作,因为我已经单独测试了它,我的弹出代码也正在工作,但我无法让它们一起工作。

HTML

<html>
  <head>
    <title> Dashboard </title>
  </head>
  <body>
    <button id='myBtn'>Click</button>
  </body>
</html>

JS

const btn = document.getElementById('myBtn');



btn.addEventListener('click', function(){
  
  const popupWindow = window.open('',  'popup', "width=600,height=450,scrollbars=no");

  const codeData = `<!DOCTYPE html>
<html id="app" lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>Login - Spotify</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <base href="/">
  <link rel="icon" href="https://accounts.scdn.co/sso/images/favicon.ace4d8543bbb017893402a1e9d1ac1fa.ico">
  <script defer src="https://accounts.scdn.co/sso/js/indexReact.80b656d1587f8f6dc120.js" sp-bootstrap></script>
  <meta id="bootstrap-data" sp-bootstrap-data='{"phoneFeatureEnabled":true,"previewEnabled":false,"user":false,"tpaState":"AQAUyYkSh59ZWwsaoxktt0QP0peVoqudQySwwaRggIRzjIDvJXSPb1XkA+h2SMWxsB4S7lHzObldMs9cX00OyB2SBsLzsgtTmYjqR1Ep6pTiDLfTa8LwlUu7mfJr2i2ZilhhGkRzXztEVTtBeyl1JvTF2OS7QqA/bOYdFtz6yQPiJ7dA5LKaOdJQi6gIqWzfGqIXnTyxxx9Ok/uRa2YSzaPtUPGrjRAx1Z4pkUTc6QmEPJbl+fn+QiJT9LTUrIWw/0rmCj61J0EIY30wX5lFftxu7GWLorgOcG+iGluxKqGMP0dG41j8nKRZzFqV40MlgAoJOk8KYSYZ8Q4Xeeejvug+hVAQylQ1f3o98E+/KC19RPhfrENshoyNm9Xhz+aV+n3qXrTkSE/2wh0JDSVc+uK+vT0sk44eBji9FSnl2C+N+Pmn16uCOBvDaUFm+MLEdTgIwncGT6EmFamF7+JwHkf6j7aeySj6rr7NSkZBWrUivkmRi2Lsfw9B2Z5LGRtXxtAC9k/h2uhDNq9RW/WMxt6PBQEIH5AzbN8P35Ns8thrBSIr/ajViJXQ8q9rckEYMOCfsP3wABSWarVkPd8L2H5EitFYK6e5usTlEW3w3/kALZ9T+1I9LLrGIOt8XQGtvR+F1daROn83bt/oKkDuHvHYx4bX7+NnWHJHKoX2Dahta1q16auFoppSolY/XBVdCGO1J9RePaoOMja7Pj2L0LfKrePy7zse0n+0xiMQ9oZtXQ==","geoLocationCountryCode":"IN","state":"","flowCtx":"dac5b50d-741f-4095-b401-fa87bfd499f4:1705629847","BON":["0","0",-1672731924]}' sp-component="login" sp-translations-data='eyJlcnJvclRpdGxlIjoiRXJyb3IiLCJsb2dpblRpdGxlIjoiTG9naW4iLCJmb3Jnb3RZb3VyUGFzc3dvcmRVc2VybmFtZSI6IkZvcmdvdCB5b3VyIHBhc3N3b3JkPyIsImRvbnRIYXZlQW5BY2NvdW50IjoiRG9uJ3QgaGF2ZSBhbiBhY2NvdW50PyIsImlucHV0VXNlcm5hbWUiOiJFbWFpbCBhZGRyZXNzIG9yIHVzZXJuYW1lIiwiaW5wdXRFbWFpbE9yVXNlcm5hbWUiOiJFbWFpbCBvciB1c2VybmFtZSIsImlucHV0UGFzc3dvcmQiOiJQYXNzd29yZCIsImNoZWNrYm94UmVtZW1iZXJNZSI6IlJlbWVtYmVyIG1lIiwiZXJyb3JGb3JtRGVmYXVsdCI6Ik9vcHMhIFNvbWV0aGluZyB3ZW50IHdyb25nLCBwbGVhc2UgdHJ5IGFnYWluIG9yIGNoZWNrIG91dCBvdXIgPGhlbHBMaW5rPmhlbHAgYXJlYTwvaGVscExpbms+IiwiZXJyb3JJbnZhbGlkQ3JlZGVudGlhbHMiOiJJbmNvcnJlY3QgdXNlcm5hbWUgb3IgcGFzc3dvcmQuIiwiZXJyb3JJbnZhbGlkQ3JlZGVudGlhbHNJbXByb3ZlZCI6IkluY29ycmVjdCBlbWFpbCBhZGRyZXNzLCB1c2VybmFtZSBvciBwYXNzd29yZC4iLCJlcnJvclVua25vd24iOiJPb3BzISBTb21ldGhpbmcgd2VudCB3cm9uZywgcGxlYXNlIHRyeSBhZ2FpbiBvciBjaGVjayBvdXQgb3VyIDxoZWxwTGluaz5oZWxwIGFyZWE8L2hlbHBMaW5rPiIsImVycm9yVHJhbnNpZW50IjoiQW4gZXJyb3IgaGFzIG9jY3VycmVkIHByb2Nlc3NpbmcgeW91ciBsb2dpbi4gUGxlYXNlIHRyeSBhZ2Fpbi4iLCJlcnJvckZhY2Vib29rQWNjb3VudCI6IllvdSBkbyBub3QgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCBjb25uZWN0ZWQgdG8geW91ciBGYWNlYm9vayBhY2NvdW50LiBJZiB5b3UgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCwgcGxlYXNlIGxvZyBpbiB3aXRoIHlvdXIgU3BvdGlmeSBjcmVkZW50aWFscy4gSWYgeW91IGRvIG5vdCBoYXZlIGEgU3BvdGlmeSBhY2NvdW50LCA8bGlua1dpdGhIcmVmPnNpZ24gdXA8L2xpbmtXaXRoSHJlZj4uIiwiZXJyb3JTZXJ2ZXJFcnJvciI6IkFuIGVycm9yIGhhcyBvY2N1cnJlZCBwcm9jZXNzaW5nIHlvdXIgcmVxdWVzdC4gUGxlYXNlIHRyeSBhZ2Fpbi4iLCJlcnJvclVzZXJuYW1lUmVxdWlyZWQiOiJQbGVhc2UgZW50ZXIgeW91ciBTcG90aWZ5IHVzZXJuYW1lIG9yIGVtYWlsIGFkZHJlc3MuIiwiZXJyb3JVc2VybmFtZUludmFsaWRDaGFyYWN0ZXJzIjoiRm9yYmlkZGVuIGNoYXJhY3RlcihzKSB7Zm9yYmlkZGVuQ2hhcnN9IGluIHVzZXJuYW1lLiIsImVycm9yUGFzc3dvcmRSZXF1aXJlZCI6IlBsZWFzZSBlbnRlciB5b3VyIHBhc3N3b3JkLiIsImVycm9yTm9JbnRlcm5ldENvbm5lY3Rpdml0eSI6IlByb2JsZW0gY29ubmVjdGluZy4gQ2hlY2sgeW91ciBpbnRlcm5ldCBjb25uZWN0aW9uIGFuZCB7dHJ5QWdhaW5MaW5rfS4iLCJlcnJvclRyeUFnYWluIjoidHJ5IGFnYWluIiwibG9nSW4iOiJMb2cgSW4iLCJsb2dJblRvU3BvdGlmeSI6IkxvZyBpbiB0byBTcG90aWZ5Iiwic2lnblVwRm9yU3BvdGlmeSI6IlNpZ24gdXAgZm9yIFNwb3RpZnkiLCJvciI6Im9yIiwibG9naW5Ub0NvbnRpbnVlIjoiVG8gY29udGludWUsIGxvZyBpbiB0byBTcG90aWZ5LiIsImVycm9yVmFsaWRhdGlvbkludmFsaWRDb2RlIjoiVGhpcyBjb2RlIGlzIGludmFsaWQuIENoZWNrIHRoZSBTTVMgYW5kIHRyeSBhZ2Fpbi4iLCJlcnJvclN1Ym1pdFRvb2tUb29Mb25nVG9DcmVhdGUiOiJJdCB0b29rIHRvbyBsb25nIHRvIGNvbXBsZXRlIHlvdXIgcmVxdWVzdC4gVHJ5IGFnYWluLiIsImVycm9yQXBwbGVBY2NvdW50IjoiWW91IGRvIG5vdCBoYXZlIGEgU3BvdGlmeSBhY2NvdW50IGNvbm5lY3RlZCB0byB5b3VyIEFwcGxlIElELiBJZiB5b3UgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCwgcGxlYXNlIHRyeSBsb2cgaW4gd2l0aCB5b3VyIFNwb3RpZnkgZW1haWwgb3IgdXNlcm5hbWUuIElmIHlvdSBkbyBub3QgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCwgcGxlYXNlIHNpZ24gdXAuIiwiY29udGludWVXaXRoQXBwbGUiOiJDb250aW51ZSB3aXRoIEFwcGxlIiwiY29udGludWVXaXRoRmFjZWJvb2siOiJDb250aW51ZSB3aXRoIEZhY2Vib29rIiwiY29udGludWVXaXRoUGhvbmVOdW1iZXIiOiJDb250aW51ZSB3aXRoIHBob25lIG51bWJlciIsImNvbnRpbnVlV2l0aEdvb2dsZSI6IkNvbnRpbnVlIHdpdGggR29vZ2xlIiwiZXJyb3JHb29nbGVBY2NvdW50IjoiWW91IGRvIG5vdCBoYXZlIGEgU3BvdGlmeSBhY2NvdW50IGNvbm5lY3RlZCB0byB5b3VyIEdvb2dsZSBBY2NvdW50LiBJZiB5b3UgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCwgcGxlYXNlIHRyeSBsb2cgaW4gd2l0aCB5b3VyIFNwb3RpZnkgZW1haWwgb3IgdXNlcm5hbWUuIElmIHlvdSBkbyBub3QgaGF2ZSBhIFNwb3RpZnkgYWNjb3VudCwgcGxlYXNlIHNpZ24gdXAuIiwicmVjYXB0Y2hhTGVnYWxOb3RpY2UiOiJUaGlzIHNpdGUgaXMgcHJvdGVjdGVkIGJ5IHJlQ0FQVENIQSBhbmQgdGhlIEdvb2dsZSA8Z29vZ2xlUHJpdmFjeVBvbGljeUxpbms+UHJpdmFjeSBQb2xpY3k8L2dvb2dsZVByaXZhY3lQb2xpY3lMaW5rPiBhbmQgPGdvb2dsZVRlcm1zTGluaz5UZXJtcyBvZiBTZXJ2aWNlPC9nb29nbGVUZXJtc0xpbms+IGFwcGx5LiIsImxvZ2luV2l0aG91dFBhc3N3b3JkIjoiTG9nIGluIHdpdGhvdXQgcGFzc3dvcmQiLCJtYWdpY19saW5rX3BvcHVwX2hlYWRlciI6IkhhdmluZyB0cm91YmxlIGxvZ2dpbmcgaW4/IiwibWFnaWNfbGlua19wb3B1cF9ib2R5IjoiV2Ugc2VudCBhbiBlbWFpbCB3aXRoIGEgbGluayB0aGF0IHdpbGwgbG9nIHlvdSBpbiB3aXRob3V0IGEgcGFzc3dvcmQuIiwiZGlhbG9nX19hY3Rpb25fcmV0cnlfbG9naW4iOiJUcnkgYW5vdGhlciBwYXNzd29yZCJ9'>
  <style>
    body {
      background-color: #121212;
      margin: 0;
    }
    #root {
      min-height: 100vh;
    }
    .loading-indicator-container {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .loading-indicator-container * {
      box-sizing: border-box;
    }
    .loading-indicator {
      content: "";
      width: 56px;
      inline-size: 56px;
      block-size: 12.4px;
      height: 12.4px;
      overflow-clip-margin: content-box;
      overflow: hidden;
    }
    .loading-indicator circle {
      fill: white;
      animation: loading-indicator-kf 1.32s linear infinite;
      transform-origin: center center;
      opacity: 0.5;
    }
    .loading-indicator circle:nth-of-type(2) {
      animation-delay: 0.1s;
    }
    .loading-indicator circle:nth-of-type(3) {
      animation-delay: 0.2s;
    }
    @keyframes loading-indicator-kf {
      0% {
        animation-timing-function: cubic-bezier(1, 0, 0.7, 1);
        opacity: 0.5;
        transform: scale(1);
      }
      40% {
        animation-timing-function: cubic-bezier(0.3, 0, 0, 1);
        opacity: 0.75;
        transform: scale(1.3);
      }
      72.5% {
        animation-timing-function: linear;
        opacity: 0.5;
        transform: scale(1);
      }
      100% {
        opacity: 0.5;
        transform: scale(1);
      }
    }
  </style>
</head>
<body>
<div id="root">
  <div class="loading-indicator-container">
    <svg class="loading-indicator" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 1 100" xml:space="preserve" role="progressbar" aria-valuetext="Loading">
      <circle stroke="none" cx="-140" cy="50" r="32"></circle>
      <circle stroke="none" cx="0" cy="50" r="32"></circle>
      <circle stroke="none" cx="140" cy="50" r="32"></circle>
    </svg>
  </div>
</div>
</body>
</html>
`;
  const codeData2 = `<html><body><h1>MissingOut</h1></body></html>`
  popupWindow.document.write(codeData);  
});

查看此 codepen 亲自查看问题。我已经单独测试了代码,检查了控制台和网络选项卡,但我不明白为什么 Spotify HTML 代码被更改为在弹出窗口中加载点代码。

更新1

新窗口中的 HTML 代码实际上与 Spotify HTML 代码没有什么不同。该问题很可能是由于未加载的元素应该来自正在加载的 .现在的问题是为什么这些脚本在新窗口或新弹出窗口中加载时遇到问题。

javascript html popup spotify
1个回答
0
投票

根据 document.write() 上的 MDN 文档

明确允许用户代理避免执行通过此方法插入的脚本元素。更糟糕的是,在某些情况下,此方法的确切行为可能取决于网络延迟,这可能会导致难以调试的故障。

连同围绕

document.write()
的其他不一致和不直观的行为,通常不鼓励使用它。

您可以在this SO question上阅读更多有关潜在替代方案的信息,但您可以使用更传统的 DOM 操作技术来完成您正在寻找的内容。

下面的示例 JS 使用常规 DOM 操作成功加载您的脚本

const btn = document.getElementById("myBtn");

btn.addEventListener("click", function () {
  const popupWindow = window.open("", "_blank");

  const codeData = `
    
<div id="root">
  <div class="loading-indicator-container">
    <svg class="loading-indicator" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 1 100" xml:space="preserve" role="progressbar" aria-valuetext="Loading">
      <circle stroke="none" cx="-140" cy="50" r="32"></circle>
      <circle stroke="none" cx="0" cy="50" r="32"></circle>
      <circle stroke="none" cx="140" cy="50" r="32"></circle>
    </svg>
  </div>
</div>
<style>
    body {
      background-color: #121212;
      margin: 0;
    }
    #root {
      min-height: 100vh;
    }
    .loading-indicator-container {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .loading-indicator-container * {
      box-sizing: border-box;
    }
    .loading-indicator {
      content: "";
      width: 56px;
      inline-size: 56px;
      block-size: 12.4px;
      height: 12.4px;
      overflow-clip-margin: content-box;
      overflow: hidden;
    }
    .loading-indicator circle {
      fill: white;
      animation: loading-indicator-kf 1.32s linear infinite;
      transform-origin: center center;
      opacity: 0.5;
    }
    .loading-indicator circle:nth-of-type(2) {
      animation-delay: 0.1s;
    }
    .loading-indicator circle:nth-of-type(3) {
      animation-delay: 0.2s;
    }
    @keyframes loading-indicator-kf {
      0% {
        animation-timing-function: cubic-bezier(1, 0, 0.7, 1);
        opacity: 0.5;
        transform: scale(1);
      }
      40% {
        animation-timing-function: cubic-bezier(0.3, 0, 0, 1);
        opacity: 0.75;
        transform: scale(1.3);
      }
      72.5% {
        animation-timing-function: linear;
        opacity: 0.5;
        transform: scale(1);
      }
      100% {
        opacity: 0.5;
        transform: scale(1);
      }
    }
  </style>
</body>
</html>
`;
  const codeData2 = `<html><body><h1>MissingOut</h1></body></html>`;
  popupWindow.document.body.innerHTML = codeData;
  const metaElement = popupWindow.document.createElement("meta");
  popupWindow.document.head.appendChild(metaElement);
  metaElement.outerHTML = `<meta id="bootstrap-data" sp-bootstrap-data='...'>`;

  popupWindow.document.getElementsByTagName("html")[0].id = "app";
  popupWindow.document.getElementsByTagName("html")[0].lang = "en";
  popupWindow.document.getElementsByTagName("html")[0].dir = "ltr";
  const scriptElement = popupWindow.document.createElement("script");
  scriptElement.setAttribute(
    "src",
    "https://accounts.scdn.co/sso/js/indexReact.80b656d1587f8f6dc120.js"
  );

  popupWindow.document.body.appendChild(scriptElement);
});

© www.soinside.com 2019 - 2024. All rights reserved.