Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应路由器URL don';刷新或手动写入时无法工作_Javascript_Reactjs_Url_React Router - Fatal编程技术网

Javascript 反应路由器URL don';刷新或手动写入时无法工作

Javascript 反应路由器URL don';刷新或手动写入时无法工作,javascript,reactjs,url,react-router,Javascript,Reactjs,Url,React Router,我正在使用React路由器,当我点击链接按钮时,它工作正常,但当我刷新网页时,它不会加载我想要的内容 例如,我在localhost/joblist中,一切都很好,因为我按了一个链接到达这里。但如果我刷新网页,我会得到: 无法获取/作业列表 默认情况下,它不是这样工作的。最初我的URL是localhost/#/和localhost/#/joblist,它们工作得非常好。但我不喜欢这种URL,所以试图删除它,我写道: Router.run(routes, Router.HistoryLocatio

我正在使用React路由器,当我点击链接按钮时,它工作正常,但当我刷新网页时,它不会加载我想要的内容

例如,我在
localhost/joblist
中,一切都很好,因为我按了一个链接到达这里。但如果我刷新网页,我会得到:

无法获取/作业列表
默认情况下,它不是这样工作的。最初我的URL是
localhost/#/
localhost/#/joblist
,它们工作得非常好。但我不喜欢这种URL,所以试图删除它,我写道:

Router.run(routes, Router.HistoryLocation, function (Handler) {
 React.render(<Handler/>, document.body);
});

路由器可以用两种不同的方式调用,这取决于导航是在客户机上进行还是在服务器上进行。您已将其配置为客户端操作。关键参数是位置的第二个参数

当您使用React Router链接组件时,它会阻止浏览器导航并调用Transitiono来执行客户端导航。您使用的是HistoryLocation,因此它使用HTML5历史API通过模拟地址栏中的新URL来完成导航的假象。如果您使用的是较旧的浏览器,这将不起作用。您需要使用HashLocation组件

当您点击刷新时,您将绕过所有React和React路由器代码。服务器获取对
/joblist
的请求,它必须返回一些内容。在服务器上,您需要将请求的路径传递给
run
方法,以便它呈现正确的视图。您可以使用相同的路线图,但可能需要对
路由器进行不同的调用。运行
。正如Charles指出的,您可以使用URL重写来处理这个问题。另一个选项是使用node.js服务器处理所有请求,并将path值作为location参数传递

例如,在express中,它可能如下所示:

var app = express();

app.get('*', function (req, res) { // This wildcard method handles all requests

    Router.run(routes, req.path, function (Handler, state) {
        var element = React.createElement(Handler);
        var html = React.renderToString(element);
        res.render('main', { content: html });
    });
});

请注意,请求路径正在传递到
run
。要做到这一点,您需要有一个服务器端视图引擎,您可以将呈现的HTML传递给该引擎。使用
renderToString
和在服务器上运行React时还有许多其他注意事项。一旦页面在服务器上呈现,当应用程序加载到客户端时,它将再次呈现,并根据需要更新服务器端呈现的HTML。

路由器可以通过两种不同的方式调用,具体取决于导航是在客户端还是在服务器上进行。您已将其配置为客户端操作。关键参数是位置的第二个参数

当您使用React Router链接组件时,它会阻止浏览器导航并调用Transitiono来执行客户端导航。您使用的是HistoryLocation,因此它使用HTML5历史API通过模拟地址栏中的新URL来完成导航的假象。如果您使用的是较旧的浏览器,这将不起作用。您需要使用HashLocation组件

当您点击刷新时,您将绕过所有React和React路由器代码。服务器获取对
/joblist
的请求,它必须返回一些内容。在服务器上,您需要将请求的路径传递给
run
方法,以便它呈现正确的视图。您可以使用相同的路线图,但可能需要对
路由器进行不同的调用。运行
。正如Charles指出的,您可以使用URL重写来处理这个问题。另一个选项是使用node.js服务器处理所有请求,并将path值作为location参数传递

例如,在express中,它可能如下所示:

var app = express();

app.get('*', function (req, res) { // This wildcard method handles all requests

    Router.run(routes, req.path, function (Handler, state) {
        var element = React.createElement(Handler);
        var html = React.renderToString(element);
        res.render('main', { content: html });
    });
});
请注意,请求路径正在传递到
run
。要做到这一点,您需要有一个服务器端视图引擎,您可以将呈现的HTML传递给该引擎。使用
renderToString
和在服务器上运行React时还有许多其他注意事项。在服务器上呈现页面后,当您的应用程序加载到客户端时,它将再次呈现,并根据需要更新服务器端呈现的HTML。

查看对已接受答案的评论以及此问题的一般性质(“不起作用”),我认为这可能是一个对这里涉及的问题进行一般性解释的好地方。因此,这个答案旨在作为OP特定用例的背景信息/详细说明。请接受我的回答

服务器端与客户端 关于这一点,首先要了解的是,现在有2个地方可以解释URL,而在“旧时代”中只有1个。在过去,当生活很简单的时候,一些用户发送了一个
http://example.com/about
发送到服务器,服务器检查URL的路径部分,确定用户正在请求关于页面,然后将该页面发回

使用React路由器提供的客户端路由,事情就不那么简单了。首先,客户端还没有加载任何JS代码。因此,第一个请求总是发送到服务器。然后,它将返回一个页面,其中包含加载React和React Router等所需的脚本标记。只有当这些脚本已加载时,阶段2才会启动。在第2阶段,例如,当用户单击“关于我们”导航链接时,URL仅在本地更改为
http://example.com/about
(由提供),但未向服务器发出请求。相反,React Router在客户端执行其操作,确定要渲染的React视图,并对其进行渲染。假设您的about页面不需要进行任何REST调用,那么它已经完成了。您已从家中转到About Us,但未触发任何服务器请求

因此,基本上,当您单击一个链接时,会运行一些Javascript来操纵地址栏中的URL,而不会导致页面刷新,从而导致React Router在客户端执行页面转换

但是现在考虑一下如果复制粘贴地址栏中的URL会发生什么

<script>
  System.config({ baseURL: '/' });
</script>
devServer: {
   historyApiFallback: true,
   contentBase: './',
   hot: true
},
<Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]
</IfModule>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- WELCOME FILE LIST -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <!-- ERROR PAGES DEFINITION -->
    <error-page>
        <error-code>404</error-code>
        <location>/index.jsp</location>
    </error-page>

</web-app>
<Router history={hashHistory} >
   <Route path="/home" component={Home} />
   <Route path="/aboutus" component={AboutUs} />
</Router>
sudo npm run build
<VirtualHost *:80>
    ServerAdmin admin@0.0.0.0
    ServerName 0.0.0.0
    ServerAlias 0.0.0.0
    DocumentRoot /var/www/html/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    <Directory "/var/www/html/">
            Options Indexes FollowSymLinks
            AllowOverride all
            Require all granted
    </Directory>
</VirtualHost>
cd /etc/apache2/sites-available
sudo a2ensite sample.conf
   RewriteEngine On
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_FILENAME} !-l
   RewriteRule ^.*$ / [L,QSA]
<Router history={hashHistory} >
import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
    <remove statusCode="500" subStatusCode="100" />
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" path="/" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
    <error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
</httpErrors>
/*  /index.html  200
// app.js

import { BrowserRouter as Router } from 'react-router-dom'

const App = () {
  render() {
    return (
        <Router>
           // your routes here
        </Router>
    )
  }
}
// server.js

app.get('/*', function(req, res) {   
  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
    if (err) {
      res.status(500).send(err)
    }
  })
})
location / {
    try_files $uri /index.html;
}
location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.html break;
  }
}
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
devServer: {
    historyApiFallback: true
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>
<script src="{{ URL::to('js/user/spa.js') }}"></script>
Route::get('/setting-alerts', function () {
   return view('user.set-alerts');
});
Route::get('/setting-alerts/{spa?}', function () {
  return view('user.set-alerts');
});
expressApp.get('/*', (request, response) => {
    response.sendFile(path.join(__dirname, '../public/index.html'));
});
<base href="/">
<!-- This must come before the css and javascripts -->
webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback
class App extends Component {
    render() {
        return (
            <Router history={browserHistory}>
                <div>
                    <Root>
                        <Switch>
                            <Route exact path={"/"} component={Home} />    
                            <Route path={"/home"} component={Home} />
                            <Route path={"/createnewproject"} component={CreateNewProject} />
                            <Route path={"/projects"} component={Projects} />
                            <Route path="*" component={NotFoundRoute} />
                        </Switch>
                    </Root>
                </div>
            </Router>
        )
    }
}
render (<App />, window.document.getElementById("app"));
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

RewriteRule ^ /index.html [L]  
{ 
  "hosting": {
    "rewrites": [{
      "source":"**",
      "destination": "/index.html"
    }]    
  }
}
module.exports = {
  entry: './app/index.js',
  output: {
       path: path.join(__dirname, '/bundle'),
       filename: 'index_bundle.js',
       publicPath: '/'
  },
<IfModule mod_rewrite.c>

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

</IfModule>
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            var url = Request.Path + Request.QueryString;
            return App(url);
        }

        [Route("App")]
        public IActionResult App(string url)
        {
            return View("/wwwroot/app/build/index.html");
        }
   }
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
"start": "webpack-dev-server --inline --content-base . --history-api-fallback"
@Controller
public class ForwardingController {
    @RequestMapping("/<any end point name>/{path:[^\\.]+}/**")
    public String forward(HttpServletRequest httpServletRequest) {
        return "forward:/";
    }
}
import {
  Router //replace Router
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <Router history={history}> //replace here saying Router
            <Layout/>
        </Router>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
import {
  HashRouter //replaced with HashRouter
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <HashRouter history={history}> //replaced with HashRouter
            <Layout/>
        </HashRouter>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <defaultDocument>
            <files>
                <remove value="default.aspx" />
                <remove value="iisstart.htm" />
                <remove value="index.htm" />
                <remove value="Default.asp" />
                <remove value="Default.htm" />
            </files>
        </defaultDocument>
        <rewrite>
            <rules>
                <rule name="React Routes" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/YOURVIRTUALDIRECTORYNAME/" />
                </rule>
            </rules>
        </rewrite>
        <directoryBrowse enabled="false" />
        <httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
            <remove statusCode="500" subStatusCode="100" />
            <remove statusCode="500" subStatusCode="-1" />
            <remove statusCode="404" subStatusCode="-1" />
            <remove statusCode="403" subStatusCode="18" />
            <error statusCode="403" subStatusCode="18" path="/YOURVIRTUALDIRECTORYNAME/" responseMode="ExecuteURL" />
            <error statusCode="404" path="/YOURVIRTUALDIRECTORYNAME/" responseMode="ExecuteURL" />
            <error statusCode="500" prefixLanguageFilePath="" path="/YOURVIRTUALDIRECTORYNAME/" responseMode="ExecuteURL" />
            <error statusCode="500" subStatusCode="100" path="/YOURVIRTUALDIRECTORYNAME/" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
</configuration>
{
  "name": "sicon.react.crm",
  "version": "0.1.0",
  "private": true,
  "homepage": "/YOURVIRTUALDIRECTORYNAME/",
  "dependencies": {
...
import  {createBrowserHistory } from 'history';

export default createBrowserHistory({
    //Pass the public URL as the base name for the router basename: process.env.PUBLIC_URL
});
  <Router history={history} basename={process.env.PUBLIC_URL}>
  <base href="%PUBLIC_URL%/">