首页 > 解决方案 > 跨站点 iframe 在 heroku 部署中中断。Redux 商店可能是罪魁祸首?

问题描述

我在我的 react 应用程序中有一些 iframe 嵌入,它们在本地运行良好,但最终在 heroku 中为空白。它们都是 https soundcloud 或 youtube 嵌入,并且是动态呈现的。我的 Heroku 日志或网络选项卡中没有弹出相关错误。heroku 日志和网络选项卡都显示了完全相同的内容,但奇怪的是没有提及获取 iframe 嵌入或加载它们或其他任何内容。有趣的是,我在 soundcloud 和 youtube 的页面上设置了各种静态工作的 iframe,当动态呈现时,没有跨站点错误,没有 cors 问题,它们的工作方式与我在本地部署时的工作方式完全相同,而且它们都使用与空白网址相同的嵌入网址。更奇怪的是,应用程序的所有其他功能都完全不受部署到 heroku 的影响。我可以从数据库中添加和减去条目并获取它们。这些操作都需要一些跨站点技巧和各种其他黑客,即使在 heroku 上也能正常工作。只是从我的数据库对象加载的 iframe 在部署在 heroku 上时似乎会中断,但在本地部署时不会中断。

我知道所有这些都只是在没有任何代码或图像的情况下悬而未决,因此我将尝试通过屏幕截图和应用程序的来源尽可能地澄清,因此我们可以排除一些可能性。

iframe 展示的主要结构是这样的:

  1. 后端服务器连接到 mongodb 数据库

  2. Mongodb 将嵌入的 url 提供给应用程序

  3. Redux 获取数据库信息并将其添加到它的存储中,它提供给反应前端

  4. React 前端获取数据库信息并将它们作为道具发送到组件行,直到最终到达一个名为“Embed.js”的组件

  5. 这个嵌入组件只是一个带有一点 javascript 的 iframe,其中“src”参数是,这个 javascript 对数据库中数据的 url 属性进行最后一些修改,使其成为正确的嵌入 url。

  6. iframe 工作并以正确的嵌入显示。

现在这一切都在本地运行良好,但在 heroku 中,其中一个部分明显中断并给出了一个空白元素。

从推断和故障排除我知道后端连接到数据库(证实这一点的正面日志),我知道数据库可以正确地将数据从服务器日志和其他功能工作的后端提供,我知道反应前端工作和所有道具在本地是有效的,我知道嵌入组件在故障排除和本地生产中可以正常工作。所以剩下的唯一问题是redux商店......当我检查heroku应用程序上的devtools时,它说找不到商店。

所以我相当有信心这是问题所在,部署到 heroku 的某些东西破坏了我的 redux 存储,并且所有 iframe 都没有获得必要的信息。这就是为什么它们是空白的。

这是我的 redux 商店的代码:

import {createStore, applyMiddleware, compose} from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";

const middleware = [thunk]

const store = createStore(
    rootReducer, /* preloadedState, */
    compose(
        applyMiddleware(...middleware)
    )

);

export default store

非常感谢任何帮助,因为我不确定从哪里真正开始解决这个问题并且还没有找到任何其他类似的问题。商店可能与它无关,我错了。

编辑1:

import React, { Component } from 'react';
import PropTypes from "prop-types";
import {Container} from "reactstrap";
// const videoUrlToID = /(?<=v=).*/
const videoUrlToID = /(?<=v=).{11}(?!list)/

export class Embed extends Component {

    makeEmbed = (url) => {

        if (url.match(/soundcloud/) === "soundcloud") {
            let Video = "https://w.soundcloud.com/player/?visual=true&url=" + url + "&auto_play=true&show_artwork=true"
            return Video;
        }

        if (url.match(/youtube/) === "youtube") {
            let videoID = url.match(videoUrlToID)
            let Video = "https://www.youtube.com/embed/" + videoID + "?autoplay=1" + "&rel=0" + "&vq=144p"
            return Video;
        }

    }

    render() {

        if (this.props.isOpen === true) return (

            <Container>
                {/* This works */}
                <iframe allowfullscreen="allowfullscreen" frameborder="0" loading="eager" importance="high" src={"https://www.youtube.com/embed/" + this.props.item.url.match(/(?<=v=).{11}(?!list)/) + "?autoplay=1" + "&rel=0" + "&vq=144p"}/>
                {/* This does not work in heroku */}
                <iframe allowfullscreen="allowfullscreen" frameborder="0" loading="eager" importance="high" src={this.makeEmbed(this.props.item.url)}/>
            </Container>

        )

        else return null;

    }

}

// PropTypes
Embed.propTypes = {
    item: PropTypes.object.isRequired,
    next: PropTypes.func.isRequired
}

export default Embed;

第一个 iframe 有效。第二个 iframe 仅在本地工作,而不在 heroku 中工作!

最终编辑:

<iframe allowfullscreen="allowfullscreen" frameborder="0" loading="eager" importance="high" src={((this.props.item.url.match(/soundcloud/)) ? "https://w.soundcloud.com/player/?visual=true&url=" + this.props.item.url + "&auto_play=true&show_artwork=true" : "https://www.youtube.com/embed/" + this.props.item.url.match(/(?<=v=).{11}(?!list)/) + "?autoplay=1" + "&rel=0" + "&vq=144p")}/>

解决方案:使用内联三元运算符来规避 Heroku 中的 react 函数中断。

标签: javascriptreactjsiframereduxreact-redux

解决方案


推荐阅读