reactjs - React.js 错误 : The service worker navigation preload request was cancelled before 'preloadResponse' settled

标签 reactjs redux redux-saga

我的 React 应用程序(使用 Redux Saga)有问题,出现控制台错误:

The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.
我只在 Chrome 的控制台上看到此错误,在 Firefox 或 Edge 中没有。
此错误不会影响我的应用程序。
以下步骤重现错误:
1. 主页上传。
enter image description here
2. 进入电影详情页面。
enter image description here
3. 返回主页面。
enter image description here
Main.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { mainActions } from '../../store/actions/actions';
import './Main.scss';
import { MoviesList, SearchPanel } from '../../components';

const propTypes = {};
const defaultProps = {};

class Main extends Component {

  constructor(props) {
    super(props);
    this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
    this.handleLoadMoreButtonClick = this.handleLoadMoreButtonClick.bind(this);
    this.handleMovieClick = this.handleMovieClick.bind(this);
    this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
  }

  componentDidMount() {
    this.handleComponentDidMount();
  }

  handleComponentDidMount() {
    const { moviesList } = this.props;
    if (!moviesList || moviesList.length <= 0) {
      this.getMovies(null, false);
    }
  }

  handleLoadMoreButtonClick() {
    this.getMovies(null, false);
  }

  handleMovieClick(e) {
    if (e.target.className === 'movie') {
      this.props.history.push(`/details/${e.currentTarget.dataset.id}`);
    }
  }

  handleSearchTextChange(e) {
    const { pageNumber, favoriteMoviesList } = this.props;
    this.props.onSearchTextChange({
      searchText: e.target.value,
      pageNumber: pageNumber,
      favoriteMoviesList: favoriteMoviesList
    });
  }

  handleFavoriteMovieClick(e) {
    const { id, name, posterId } = e.currentTarget.dataset;
    const { moviesList, favoriteMoviesList } = this.props;
    this.props.onUpdateFavoriteMovies({
      updatedMovie: { id: id, name: name, posterId: posterId },
      favoriteMoviesList: favoriteMoviesList,
      moviesList: moviesList
    });
  }

  getMovies(updatedSearchText, isSearchChange) {
    const { searchText, pageNumber, favoriteMoviesList } = this.props;
    this.props.onLoadMovies({
      pageNumber: pageNumber,
      favoriteMoviesList: favoriteMoviesList,
      updatedSearchText: isSearchChange ? updatedSearchText : searchText,
      isSearchChange: isSearchChange
    });
  }

  render() {
    const { searchText, isLoadingMoreMovies, isPager, moviesList } = this.props;
    return (
      <div className="main-area">
        <SearchPanel
          searchText={searchText}
          onSearchTextChange={this.handleSearchTextChange}
        />
        <MoviesList
          pageName='movies'
          moviesList={moviesList}
          isLoadingMoreMovies={isLoadingMoreMovies}
          isPager={isPager}
          onLoadMoreClick={this.handleLoadMoreButtonClick}
          onMovieClick={this.handleMovieClick}
          onFavoriteMovieClick={this.handleFavoriteMovieClick}
        />
      </div>
    );
  }
}

Main.propTypes = propTypes;
Main.defaultProps = defaultProps;

const mapStateToProps = (state) => {
  return {
    searchText: state.main.searchText,
    pageNumber: state.main.pageNumber,
    isLoadingMoreMovies: state.main.isLoadingMoreMovies,
    isPager: state.main.isPager,
    moviesList: state.main.moviesList,
    favoriteMoviesList: state.main.favoriteMoviesList
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onLoadMovies: (request) => dispatch(mainActions.loadMovies(request)),
    onSearchTextChange: (request) => dispatch(mainActions.searchTextChange(request)),
    onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Main);
详情.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { detailsActions, mainActions } from '../../store/actions/actions';
import './Details.scss';
import { ActorsList, ButtonClick, CrewsList, FeaturesList, PageTitle, ProductionsList, Rating, Trailer } from '../../components';
import movieUtils from '../../utils/movie.utils';

const propTypes = {};
const defaultProps = {};

class Details extends Component {
    constructor(props) {
        super(props);
        this.handleBackClick = this.handleBackClick.bind(this);
        this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
        this.isFavorite = false;
    }

    componentDidMount() {
        this.handleComponentDidMount();
    }

    handleComponentDidMount() {
        if (this.props.moviesList.length <= 0) {
            this.handleBackClick();
            return;
        }
        const movieId = this.props.match.params.id;
        if (!movieId) {
            this.handleBackClick();
            return;
        }
        this.props.onLoadMovieDetails(movieId);
        this.updateIsFavorite(movieId);
    }

    numberWithCommas(number) {
        return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }

    updateIsFavorite(movieId) {
        this.isFavorite = this.props.favoriteMoviesList.findIndex(movie => parseInt(movie.id) === parseInt(movieId)) > -1;
    }

    handleBackClick() {
        this.props.history.push(`/`);
    }

    handleFavoriteMovieClick() {
        const { movie, moviesList, favoriteMoviesList } = this.props;
        this.props.onUpdateFavoriteMovies({
            updatedMovie: { id: movie.id, name: movie.title, posterId: movie.poster_path },
            favoriteMoviesList: favoriteMoviesList,
            moviesList: moviesList
        });
        this.updateIsFavorite(movie.id);
    }

    render() {
        const { movie, youtubeKey, credits } = this.props;
        if (!movie) {
            return null;
        }
        const { adult, poster_path, budget, genres, homepage, imdb_id, original_language, original_title,
            overview, popularity, production_companies, production_countries, release_date, revenue, runtime, spoken_languages,
            status, tagline, title, video, vote_average, vote_count } = movie;
        const genresText = genres.map(genre => genre.name).join(', ');
        const countriesText = production_countries.map(country => country.name).join(', ');
        const languagesText = spoken_languages.map(language => language.name).join(', ');
        const featuresList = [
            { item: 'Release Date', value: release_date },
            { item: 'Budget', value: `$${this.numberWithCommas(budget)}` },
            { item: 'Revenue', value: `$${this.numberWithCommas(revenue)}` },
            { item: 'Length', value: `${runtime} minutes` },
            { item: 'Popularity', value: popularity },
            { item: 'Original Title', value: original_title },
            { item: 'For Adults', value: adult ? 'Yes' : 'No' },
            { item: 'Original Language', value: original_language },
            { item: 'Spoken Languages', value: languagesText },
            { item: 'Countries', value: countriesText },
            { item: 'Status', value: status },
            { item: 'Is Video', value: video ? 'Yes' : 'No' }
        ];
        const linksList = [];
        if (homepage) {
            linksList.push({ id: 1, name: 'Homepage', url: homepage });
        }
        if (imdb_id) {
            linksList.push({ id: 2, name: 'IMDB', url: `https://www.imdb.com/title/${imdb_id}` });
        }
        const actorsList = movieUtils.removeDuplicates(credits ? credits.cast ? credits.cast : null : null, 'name');
        const crewsList = movieUtils.removeDuplicates(credits ? credits.crew ? credits.crew : null : null, 'name');
        return (
            <div>
                <section className="details-area">
                    <PageTitle
                        pageName='details'
                        pageTitle='Details'
                    />
                    <ul className="details-content">
                        <li className="details-left" style={{ backgroundImage: `url('https://image.tmdb.org/t/p/original${poster_path}')` }}></li>
                        <li className="details-right">
                            <h2>{title} ({release_date.substr(0, 4)})</h2>
                            <p className="genres">{genresText}</p>
                            <p className="description short">{tagline}</p>
                            <Rating
                                rating={vote_average}
                                votesCount={this.numberWithCommas(vote_count)}
                            />
                            <p className="description full">{overview}</p>
                            <div className="extra">
                                <FeaturesList
                                    featuresList={featuresList.slice(0, 5)}
                                    linksList={null}
                                    isFavorite={this.isFavorite}
                                    onFavoriteMovieClick={this.handleFavoriteMovieClick}
                                />
                                {youtubeKey && <Trailer
                                    youtubeKey={youtubeKey}
                                />}
                            </div>
                        </li>
                        <div className="extra-features">
                            <FeaturesList
                                featuresList={featuresList.slice(5, featuresList.length)}
                                linksList={linksList}
                                isFavorite={null}
                                onFavoriteMovieClick={null}
                            />
                            <ProductionsList
                                productionsList={production_companies}
                            />
                        </div>
                    </ul>
                </section>
                <section className="actors-area">
                    <PageTitle
                        pageName='actors'
                        pageTitle='Cast'
                    />
                    <ActorsList
                        actorsList={actorsList}
                    />
                </section>
                <section className="crew-area">
                    <PageTitle
                        pageName='crew'
                        pageTitle='Crew'
                    />
                    <CrewsList
                        crewsList={crewsList}
                    />
                </section>
                <ButtonClick
                    buttonText={'Back'}
                    buttonTitle={'Back'}
                    isLoading={false}
                    onClick={this.handleBackClick}
                />
            </div>
        );
    }
}

Details.propTypes = propTypes;
Details.defaultProps = defaultProps;

const mapStateToProps = (state) => {
    return {
        movie: state.details.movie,
        youtubeKey: state.details.youtubeKey,
        credits: state.details.credits,
        moviesList: state.main.moviesList,
        favoriteMoviesList: state.main.favoriteMoviesList
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        onLoadMovieDetails: (movieId) => dispatch(detailsActions.loadDetails(movieId)),
        onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(Details);
我已经看过的:
Getting The service worker navigation preload request was cancelled before 'preloadResponse' settled
https://docs.microsoft.com/en-us/answers/questions/108004/getting-the-service-worker-navigation-preload-requ.html
https://support.google.com/mail/thread/4055804?hl=en
https://love2dev.com/pwa/service-worker-preload/
我试图把它放在 Details.jsx 页面上,但没有用:
self.addEventListener('fetch', event => {
    event.respondWith(async function () {
        // Respond from the cache if we can
        const cachedResponse = await caches.match(event.request);
        if (cachedResponse) return cachedResponse; // Else, use the preloaded response, if it's there
        const response = await event.preloadResponse;
        if (response) return response; // Else try the network.
        return fetch(event.request);
    }());
});

self.addEventListener('activate', event => {
    event.waitUntil(async function () {
        // Feature-detect
        if (self.registration.navigationPreload) { // Enable navigation preloads!
            console.log('Enable navigation preloads!');
            await self.registration.navigationPreload.enable();
        } return;
    })();
});
我该如何解决这个问题?谢谢。

最佳答案

有同样的错误,即使我的 iframe 也没有加载……无论您使用 youtube 上的什么视频,都可以使用 nocookie/嵌入 在网址中。它对我有用。
尝试更改 https://www.youtube.com/watch?v=i8eBBG46H8A
https://www.youtube-nocookie.com/embed/i8eBBG46H8A
希望 nocookie & embed 有帮助..!!

关于reactjs - React.js 错误 : The service worker navigation preload request was cancelled before 'preloadResponse' settled,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66099180/

相关文章:

javascript - 在 npm create-react-app 之后立即运行测试非常慢

css - 如何从多边形中心而不是底部制作 SVG 级别?

reactjs - 在 webpack 应用程序中引用 amd 模块(arcgis)

javascript - 如何从生成器函数内的回调函数调用 redux-saga 效果?

ruby-on-rails - 在 Rails 应用程序中集成 jsx 和 erb

javascript - Reactjs + redux : Sharing reducers across different components

reactjs - 在react组件/redux工具包之外的函数中使用useDispatch

javascript - mobx 如何知道组件绑定(bind)到哪个变量?

javascript - firebase 直接运行时 Redux saga 调用错误

reactjs - Redux/Redux Saga - 如何等待商店更新?