Warm tip: This article is reproduced from serverfault.com, please click

reactjs-只有一些从 SpaceX API 获取的嵌入式 YouTube 视频无法在浏览器中加载

(reactjs - Only some embedded YouTube videos fetched from SpaceX API do not load in browser)

发布于 2021-03-23 14:02:12

我有一个网页,我在其中显示从 SpaceX API 中提取的数据:SpaceX API

发布地点:盖茨比SpaceX数据

我正在尝试为 pastLaunches 组件中的每个发布显示一个 youtube 嵌入。我在浏览器中收到以下错误:“拒绝在框架中显示”,因为它将“X-Frame-Options”设置为“sameorigin”。我试过调整我的配置文件 (netlify.toml) 但到目前为止没有任何效果。对于拒绝加载的视频,我也只收到此错误。同样,某些视频确实会加载。看起来不起作用的视频也没有从watch/转换embed/我对 React 有点陌生,还没有处理过这种级别的功能,在我继续研究时的任何提示都是有帮助的!

这是我使用 youtube 链接的部分:

{links.video_link
                ? <iframe
                className="h-48"
            src={links.video_link && links.video_link.replace('watch?v=', 'embed/')}
            title={mission_name}
            frameBorder={0}
            allow={"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"}
            allowFullScreen={true}
            webkitallowfullscreen="true"
            mozallowfullscreen="true"
          />
          : <p>Sorry, no Youtube video is available</p>
            }

这是完整的组件:

import React, { useState, useEffect }  from 'react'
import moment from "moment"
import "../styles/tailwind.css"

const getPastLaunches = () => {
  return fetch('https://api.spacexdata.com/v3/launches/past?limit=50&sort=flight_number&order=desc')
  .then((res) => res.json())
}

const PastLaunches = () => {
  const [launches, setLaunches] = useState(null)


  useEffect(() => {
    getPastLaunches()
      .then(setLaunches)
  }, [])

  if (launches === null) {
    return <p>Loading past launches...</p>
  }

  return (
    <>
    <div className="flex flex-row justify-center items-end mx-auto mt-20 mb-4 overflow-x-visible">
        <h1 className="text-white text-2xl font-mono font-bold border-b-8 border-blue-600 mr-2" style={{lineHeight: .45}}>Recent Launches  </h1>
                <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="#ffffff">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={4} d="M19 14l-7 7m0 0l-7-7m7 7V3"  />
        </svg>
    </div>


    <ul className="grid py-2 lg:grid-cols-3 md:grid-cols-2 md:gap-2 mx-auto">
    {launches.map(launch => {
        const {flight_number, details, mission_name, launch_date_local, links, rocket, launch_site} = launch;

      return (
        <li className="max-w-sm max-h-100 flex flex-auto flex-col p-2 rounded overflow-hidden shadow-lg bg-gray-700 bg-opacity-50 text-white">
            {links.video_link
                ? <iframe
                className="h-48"
            src={links.video_link && links.video_link.replace('watch?v=', 'embed/')}
            title={mission_name}
            frameBorder={0}
            allow={"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"}
            allowFullScreen={true}
            webkitallowfullscreen="true"
            mozallowfullscreen="true"
          />
          : <p>Sorry, no Youtube video is available</p>
            }
            
            
        <div className="flex flex-col p-4 text-gray-100">
            <div className="flex flex-row justify-between items-start space-x-8 pb-2">
                <h1 className="font-bold text-lg">Rocket: {rocket.rocket_name}</h1>
                  
              <strong className="text-lg">Flight # {flight_number}</strong>
              
            </div>
             
              <p><strong>Mission: </strong>{mission_name}</p>
              <p><strong>Location: </strong>{launch_site.site_name_long}</p>
               

              <p><strong>Launch Date: </strong>{moment(launch_date_local).format("dddd, MMMM Do YYYY, h:mm:ss a")}</p>

              {details
                ? <p className="pt-2">{details}</p>
          : <em className="text-sm pt-2">I'm sorry, no details are available for this launch</em>
            }
            
      </div>
        </li>
      );
    })}

  </ul>
</>

  )
}

export default PastLaunches

而我目前的 netlify.toml:

[build]
  functions = "/root"
  
[[headers]]
  # Define which paths this specific [[headers]] block will cover.
  for = "/*"
    [headers.values]
    Access-Control-Allow-Origin = "*"
    cache-control = '''
    max-age=0,
    no-cache,
    no-store,
    must-revalidate'''

这是错误的屏幕截图:

控制台错误

损坏视频的错误消息: 子帧错误

成功视频: 成功的视频

Questioner
Nikki Peel
Viewed
0
coreyward 2021-03-24 00:52:54

我怀疑 SpaceX 禁止嵌入他们的一些视频。X-Frame-OptionsHTTP头告诉其中内容能够通过成帧被嵌入在浏览器。sameorigin值可防止嵌入到正在检索内容的域名以外的域名上。

YouTube 视频设置中“允许嵌入”选项的屏幕截图