>  기사  >  웹 프론트엔드  >  반응 라우터에서 페이지를 새로 고칠 때 404 문제가 발생합니다.

반응 라우터에서 페이지를 새로 고칠 때 404 문제가 발생합니다.

亚连
亚连원래의
2018-06-14 15:51:342147검색

이 글은 주로 React-Router 브라우저의 404 문제에 대한 해결책을 소개합니다. 페이지를 새로 고치는 것은 매우 실용적입니다. 필요한 친구들이 참고할 수 있습니다.

React를 사용하여 새로운 프로젝트를 개발할 때 페이지를 새로 고치면 두 번째 또는 세 번째 수준에 직접 액세스할 수 있습니다. 라우팅 시 액세스가 실패하고 404 또는 리소스 로딩 예외가 발생합니다. 이 문서에서는 이 문제를 분석하고 해결 방법을 요약합니다.

Background

webpack-dev-server를 로컬 개발 서버로 사용하는 경우 일반적으로 webpack-dev-server 명령만 사용하여 시작하면 되지만 프로젝트가 다음 두 가지 상황에 있을 경우 중첩 라우팅 및 비동기 로딩 라우팅이 종종 필요합니다.

  1. 우리는 단일 페이지 애플리케이션 라우팅을 구축하기 위해 반응 라우터와 같은 라우팅 라이브러리를 사용합니다.

  2. html-webpack-plugin 플러그인을 사용하여 <를 동적으로 삽입합니다. ;script> html 문서에 로드된 js 태그

이때 localhost:9090에 액세스해야 하는 경우에는 페이지와 js 및 기타 파일을 정상적으로 로드할 수 있습니다. 세 번째 수준 라우팅 또는 페이지 새로 고침(예: localhost:9090/posts/92) 두 가지 상황이 발생할 수 있습니다.

  1. 페이지가 로드되지 않고 Cannot Get(404)이 반환됩니다. 서비스는 응답하지만 webpack 처리에 의해 출력된 html 파일이 반환되지 않아 js 리소스를 로드할 수 없게 됩니다. 두 번째 상황은 그림과 같습니다.

그러면 어떻게 해야 할까요? 각 페이지의 정상적인 액세스 및 라우팅은 무엇입니까? 해당 블로거는 문서 구성을 검색한 후 소스를 추적하고 문제를 해결했습니다. 이 글은 전체 문제 해결 과정을 요약한 것입니다.

문제 분석

문제를 발견한 후 문제를 분석하고 해결하기 시작합니다. 이 문제는 일반적으로 두 가지 이유 때문에 발생한다고 판단합니다:

react-router road front-end 구성;

  1. webpack -dev-server 서비스 구성

  2. react-router

프론트엔드 라우팅이 문제 식별이 쉽고 분석이 더 편리하며, React-Router에 더 익숙하기 때문에 먼저 쿼리하세요. React-Router 라우팅 라이브러리의 관련 구성 정보를 보면 browserHistory를 사용하면 실제 URL이 생성되고 해당 경로로 점프한 후에는 초기/요청 처리에 문제가 없다고 언급된 문서를 발견했습니다. , 페이지를 새로 고치거나 URL에 직접 액세스하면 올바르게 응답하지 않는 것을 확인할 수 있습니다. 자세한 내용은 참조 문서를 확인하세요. 문서에서는 여러 서버 구성 솔루션도 제공합니다.

Node

const express = require(&#39;express&#39;)
const path = require(&#39;path&#39;)
const port = process.env.PORT || 8080
const app = express()

// 通常用于加载静态资源
app.use(express.static(__dirname + &#39;/public&#39;))

// 在你应用 JavaScript 文件中包含了一个 script 标签
// 的 index.html 中处理任何一个 route
app.get(&#39;*&#39;, function (request, response){
 response.sendFile(path.resolve(__dirname, &#39;public&#39;, &#39;index.html&#39;))
})

app.listen(port)
console.log("server started on port " + port)

Node를 서비스로 사용하는 경우, 모든 요청을 수신하고 대상 HTML 문서(js 리소스를 참조하는 HTML)를 반환하려면 와일드카드 *를 사용해야 합니다.

Nginx

nginx 서버를 사용하는 경우 try_files 지시어만 사용해야 합니다.

server {
 ...
 location / {
  try_files $uri /index.html
 }
}
Apache

Apache 서버를 사용하는 경우 프로젝트 루트에 .htaccess 파일을 생성해야 합니다. 파일에는 다음 내용이 포함되어 있습니다.

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
다음은 서버에 대한 구성입니다. 아쉽게도 아직 관련 서버를 도입하지 않았습니다. webpack-dev-server. 문제는 라우팅 요청이 반환된 HTML 문서와 일치할 수 없다는 것입니다. 따라서 webpack-dev-server 문서에서 해결책을 찾아야 합니다.

webpack-dev-server

공식 webpack-dev-server 문서에 대해 불평해야 합니다. 블로거는 문제를 명확하게 보기 전에 여러 번 읽었습니다. 여기에는 두 가지 상황이 있습니다.

출력. publicPath가 수정되지 않았습니다. 즉, webpack 구성 파일에 선언된 값이 없습니다. 이는 기본값입니다.

  1. output.publicPath를 사용자 정의 값으로 설정하세요.

  2. 문서를 보려면 여기를 클릭하세요.

    기본값

기본적으로 output.publicPath 값은 수정되지 않습니다. webpack-dev-server의 histoApiFallback 구성만 설정하면 됩니다.

devServer: {
 historyApiFallback: true
}

HTML5 기록 API를 사용하는 경우 색인을 제공해야 할 수 있습니다. 404 응답 대신 .html을 사용합니다. 이는 HistoryApiFallback: true를 설정하여 수행할 수 있습니다.

애플리케이션이 HTML5 기록 API를 사용하는 경우 index.html을 사용하여 404 또는 문제 요청에 응답해야 할 수도 있습니다. g HistoryApiFallback: true를 설정하면 됩니다.

사용자 정의 값

그러나 Webpack 구성에서 output.publicPath를 수정한 경우 리디렉션할 URL을 지정해야 합니다. 이는 HistoryApiFallback.index 옵션

을 사용하여 수행됩니다. webpack 구성 파일에 publicPath 값이 있으면 요청 리디렉션을 선언하고 HistoryApiFallback.index 값을 구성해야 합니다.

// output.publicPath: &#39;/assets/&#39;
historyApiFallback: {
 index: &#39;/assets/&#39;
}
Proxy

위의 방법을 사용해도 문제가 완전히 해결되지 않는다는 것을 알았습니다. 라우팅 요청 응답 예외가 항상 발생했기 때문에 블로거는 계속해서 더 나은 솔루션을 찾았습니다.

문서를 보려면 여기를 클릭하세요

프록시는 함수의 반환을 기반으로 선택적으로 우회할 수 있습니다. 함수는 HTTP 요청, 응답 및 지정된 프록시 옵션을 검사할 수 있으며 프록시를 계속하는 대신 제공될 URL 경로를 반환해야 합니다. 요청하세요.

代理提供通过函数返回值响应请求方式,针对不同请求进行不同处理,函数参数接收HTTP请求和响应体,以及代理配置对象,这个函数必须返回false或URL路径,以表明如何继续处理请求,返回URL时,源请求将被代理到该URL路径请求。

proxy: {
 &#39;/&#39;: {
  target: &#39;https://api.example.com&#39;,
  secure: false,
  bypass: function(req, res, proxyOptions) {
   if (req.headers.accept.indexOf(&#39;html&#39;) !== -1) {
    console.log(&#39;Skipping proxy for browser request.&#39;);
    return &#39;/index.html&#39;;
   }
  }
 }
}

如上配置,可以监听https://api.example.com域下的/开头的请求(等效于所有请求),然后判断请求头中accept字段是否包含html,若包含,则代理请求至/index.html,随后将返回index.html文档至浏览器。

解决问题

综合以上方案,因为在webpack配置中修改了output.publicPath为/assets/,所以博主采用webpack-dev-server Proxy代理方式解决了问题:

const PUBLICPATH = &#39;/assets/&#39;
...
proxy: {
 &#39;/&#39;: {
  bypass: function (req, res, proxyOptions) {
   console.log(&#39;Skipping proxy for browser request.&#39;)
   return `${PUBLICPATH}/index.html`
  }
 }
}

监听所有前端路由,然后直接返回${PUBLICPATH}/index.html,PUBLICPATH就是设置的output.publicPath值。

另外,博主总是习惯性的声明,虽然不设置该属性也能满足预期访问效果:

historyApiFallback: true

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在JS中实现点击下拉菜单内容同步输入框

实现输入框与下拉框联动

使用parcel.js打包出错的问题

위 내용은 반응 라우터에서 페이지를 새로 고칠 때 404 문제가 발생합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.