admin管理员组

文章数量:1415491

There are a few topics on SO like this one which remends changing Webpack and this one that remends setting up a catch-all.

I am using react-router-dom for three routes; similar story to the rest of the questions on here, the / path works but neither /cars or /about does.

import React, {Component} from 'react';
import {render} from 'react-dom';
import {BrowserRouter, Route, Switch, Link} from 'react-router-dom';


const Home = () => (
  <h1>Home</h1>
)

const Car = () => (
  <h1>Cars</h1>
)

const About = () => (
  <h1>About</h1>
)

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" ponent={Home}/>
      <Route exact path="/cars" ponent={Car}/>
      <Route path="/about" ponent={About}/>
    </Switch>
  </BrowserRouter>,
  document.getElementById('container')
);

I have tried adding a publicPath and historyApiFallback into my webpack config:

module.exports = {
  entry: ['./src/index.jsx'],
  output: {
    path: path.resolve('public'),
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    loaders: [
      {test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/},
      {test: /\.jsx$/,loader: 'babel-loader',exclude: /node_modules/}
    ]
  },
  devServer: {
    historyApiFallback: true
  }
}

But as soon as I navigate to http://localhost:8080/cars I get a Cannot GET /cars message on the browser and a load of errors similar to this:

Refused to load the font 'data:font/woff;base64,d09GRgABAAAAAGz8ABEAAAAA09gAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABgAAAAC8AAAA0AsQC9UdQT1MAAAGwAAATuAAANLwBEyF1R1NVQgAAFWgAAAIWAAAEZqfk0PVPUy8yAAAXgAAAAFAAAABgaNCCw2NtYXAAABfQAAABkwAAAkQk8AV7Y3Z0IAAAGWQAAABiAAAAugGiQq9mcGdtAAAZyAAABZcAAAvNb3/BHGdhc3AAAB9gAAAACAAAAAgAAAAQZ2x5ZgAAH2gAAESvAAB8yu28l3FoZWFkAABkGAAAADYAAAA2BmibVWhoZWEAAGRQAAAAIAAAACQHMQRzaG10eAAAZHAAAAJDAAAEImBmMbxsb2NhAABmtAAAAhoAAAIaflxdR21heHAAAGjQAAAAIAAAACACjgzgbmFtZQAAaPAAAACdAAABKBQEL8lwb3N0AABpkAAAAsMAAAS9pi3QFXByZ...w76a3jVVUpJzXkBsRtNQoHWTV2mt2UusrulbnIrkvAXNBDFtTVIB8Uoau4pSruq4q7qq2dHpQADUAT0IJ5ra0yPUAfMACMFY6pOtegV/9D7UtTZx72tTeXI4JdcUXh7Pb67D7I/S05AwjAAiYsNie6WOwc4MiYCORSEx+ZExuCvQpiNSRmAdL8wDs2AslUOgp8HfnSYyfCYjrE7w8QDucyS0aXjH0zGk7FX991RgON6L7Qma6pQ+SzA0Qw1x9+HgNFtrBk+F9RsmDpTShvNJL4BDWtP8IAeAFj8N7BcCIoYiMjY1/kBsadHAwcDMkFGxnYnLZFMFgwMLAyaIE4DjzeHPYs+mzKLOIsrBxQoVA2VyZzFk0mWSawELfTPmEGAQYeBk4GNpBGTqCYgNM+BgcYhIgxM7hsVGHsCIzY4NARsZE5xWWjGoi3i6OBgZHFoSM5JAKkJBIIHHh8ORxZDNlUWSRZWHm0djD+b93A0ruRicFlA1vcRtYUFwBQJimV' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.

There are a few topics on SO like this one which remends changing Webpack and this one that remends setting up a catch-all.

I am using react-router-dom for three routes; similar story to the rest of the questions on here, the / path works but neither /cars or /about does.

import React, {Component} from 'react';
import {render} from 'react-dom';
import {BrowserRouter, Route, Switch, Link} from 'react-router-dom';


const Home = () => (
  <h1>Home</h1>
)

const Car = () => (
  <h1>Cars</h1>
)

const About = () => (
  <h1>About</h1>
)

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" ponent={Home}/>
      <Route exact path="/cars" ponent={Car}/>
      <Route path="/about" ponent={About}/>
    </Switch>
  </BrowserRouter>,
  document.getElementById('container')
);

I have tried adding a publicPath and historyApiFallback into my webpack config:

module.exports = {
  entry: ['./src/index.jsx'],
  output: {
    path: path.resolve('public'),
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    loaders: [
      {test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/},
      {test: /\.jsx$/,loader: 'babel-loader',exclude: /node_modules/}
    ]
  },
  devServer: {
    historyApiFallback: true
  }
}

But as soon as I navigate to http://localhost:8080/cars I get a Cannot GET /cars message on the browser and a load of errors similar to this:

Refused to load the font 'data:font/woff;base64,d09GRgABAAAAAGz8ABEAAAAA09gAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABgAAAAC8AAAA0AsQC9UdQT1MAAAGwAAATuAAANLwBEyF1R1NVQgAAFWgAAAIWAAAEZqfk0PVPUy8yAAAXgAAAAFAAAABgaNCCw2NtYXAAABfQAAABkwAAAkQk8AV7Y3Z0IAAAGWQAAABiAAAAugGiQq9mcGdtAAAZyAAABZcAAAvNb3/BHGdhc3AAAB9gAAAACAAAAAgAAAAQZ2x5ZgAAH2gAAESvAAB8yu28l3FoZWFkAABkGAAAADYAAAA2BmibVWhoZWEAAGRQAAAAIAAAACQHMQRzaG10eAAAZHAAAAJDAAAEImBmMbxsb2NhAABmtAAAAhoAAAIaflxdR21heHAAAGjQAAAAIAAAACACjgzgbmFtZQAAaPAAAACdAAABKBQEL8lwb3N0AABpkAAAAsMAAAS9pi3QFXByZ...w76a3jVVUpJzXkBsRtNQoHWTV2mt2UusrulbnIrkvAXNBDFtTVIB8Uoau4pSruq4q7qq2dHpQADUAT0IJ5ra0yPUAfMACMFY6pOtegV/9D7UtTZx72tTeXI4JdcUXh7Pb67D7I/S05AwjAAiYsNie6WOwc4MiYCORSEx+ZExuCvQpiNSRmAdL8wDs2AslUOgp8HfnSYyfCYjrE7w8QDucyS0aXjH0zGk7FX991RgON6L7Qma6pQ+SzA0Qw1x9+HgNFtrBk+F9RsmDpTShvNJL4BDWtP8IAeAFj8N7BcCIoYiMjY1/kBsadHAwcDMkFGxnYnLZFMFgwMLAyaIE4DjzeHPYs+mzKLOIsrBxQoVA2VyZzFk0mWSawELfTPmEGAQYeBk4GNpBGTqCYgNM+BgcYhIgxM7hsVGHsCIzY4NARsZE5xWWjGoi3i6OBgZHFoSM5JAKkJBIIHHh8ORxZDNlUWSRZWHm0djD+b93A0ruRicFlA1vcRtYUFwBQJimV' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.
Share Improve this question asked Aug 18, 2017 at 13:25 grpcMegrpcMe 1,4175 gold badges16 silver badges29 bronze badges 2
  • I tried your code here and that works for me. I understand it could be an issue with your webpack but just to point out that there's nothing wrong with the code itself. – Rowland Commented Aug 18, 2017 at 13:30
  • Thanks @Rowland - I've just figured it out so will post the answer as soon as I can :) – grpcMe Commented Aug 18, 2017 at 13:31
Add a ment  | 

2 Answers 2

Reset to default 4

Typically after trying to figure this out on my own for 30 minutes, getting frustrated and posting on SO; I figured it out 2 minutes after...!

The configuration I added into my webpack file was pointless; seeing as I am serving my files using express

The catch-all method was what I needed, but I had done it wrong. You have two options. Do a proper "catch all" and send everything to the HTML file...

app.get('*', (req, res) => {
  res.sendFile(appRootPath + '/public/index.html');
});

or, if like me, you want to only send a specific endpoint, so you can still manage 'other things' you can...

app.get('/react*', (req, res) => {
  res.sendFile(appRootPath + '/public/index.html');
});

A specific mention, because this is what tripped me up, make sure you do /react*/ and not /react/*

I could then update my Routes to the following and browse to them directly...

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/react" ponent={Home}/>
      <Route exact path="/react/car" ponent={Car}/>
      <Route path="/react/about" ponent={About}/>
    </Switch>
  </BrowserRouter>,
  document.getElementById('container')
);

I had the same problem and was able to solve it by changing my server implementation to use express with "catch all and send to index.html" as suggested by OmisNomis.

Adding here my server.js code for anyone who has no previous knowledge of express

const express = require("express")
const path = require("path")
const app = express()

app.use(express.static(__dirname))
app.get('*', (req, res) => res.sendFile(path.join(__dirname, '/index.html')))
app.listen(8080)

console.log("Running at Port 8080")

本文标签: javascriptCan39t navigate to reactrouterdom URL39sStack Overflow