Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Я использовал приложение create-react-app, чтобы сделать сайт сейчас и имел такую же проблему, что и здесь. Я использую BrowserRouting
из пакета react-router-dom
. Я работаю на сервере Nginx, и для меня это решило добавить следующее к /etc/nginx/yourconfig.conf
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
}
. Это соответствует добавлению следующего к .htaccess
в случае, если вы используете Appache
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
Это также похоже на решение, предложенное самим Facebook, и его можно найти здесь
Маршрутизатор можно вызывать двумя разными способами, в зависимости от того, происходит ли навигация на клиенте или на сервере. Он настроен для работы на стороне клиента. Ключевым параметром является второй метод run , местоположение.
Когда вы используете компонент React Router Link, он блокирует навигацию браузера и вызывает переход. Чтобы сделать клиент- боковая навигация. Вы используете HistoryLocation, поэтому он использует API истории HTML5 для завершения иллюзии навигации, моделируя новый URL-адрес в адресной строке. Если вы используете старые браузеры, это не сработает. Вам нужно будет использовать компонент HashLocation.
Когда вы нажмете обновление, вы обойдете весь код React и React Router. Сервер получает запрос для /joblist
, и он должен что-то вернуть. На сервере вам необходимо передать путь, запрошенный методу run
, чтобы он отображал правильный вид. Вы можете использовать ту же карту маршрутов, но вам, вероятно, потребуется другой вызов Router.run
. Как указывает Чарльз, вы можете использовать переписывание URL, чтобы справиться с этим. Другим вариантом является использование сервера node.js для обработки всех запросов и передачи значения пути в качестве аргумента местоположения.
В выражении, например, это может выглядеть так:
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-код на стороне сервера, если необходимо.
Здесь много хороших ответов, и здесь не нужно писать больше ответов.
, но я предоставляю еще одну хорошую ссылку здесь
https://css-tricks.com/learning-react-router/#article-header-id- 9
Если вы используете Express или некоторые другие фреймворки в бэкэнд, вы можете добавить аналогичную конфигурацию, как показано ниже, и проверить общедоступный путь Webpack в конфигурации, она должна работать нормально даже при перезагрузке, если вы используете BrowserRouter
` expressApp.get('/*', (request, response) => {
response.sendFile(path.join(__dirname, '../public/index.html'));
});`
Если вы размещаете в IIS; Добавление этого в мой webconfig решило мою проблему
<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>
Вы можете сделать аналогичную конфигурацию для любого другого сервера
Вы можете изменить htaccess и вставить это:
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
i am using react: "^15.3.2" , react-router: "^3.0.0", history: "^4.3.0",
Если вы размещаете свое приложение-ответ на IIS, просто добавьте файл web.config, содержащий:
<?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>
. Это скажет серверу IIS, чтобы вернуть основную страницу клиенту вместо ошибки 404 и нет необходимости использовать историю хэша.
Если вы используете приложение Create React:
В этой проблеме есть большая прогулка по решениям для многих крупных хостинговых платформ, которые вы можете найти ЗДЕСЬ в приложении Create React стр. Например, я использую React Router v4 и Netlify для моего внешнего кода. Все, что нужно, это добавить 1 файл в мою общую папку («_redirects») и одну строку кода в этом файле:
/* /index.html 200
Теперь мой сайт правильно отображает пути, такие как mysite.com/pricing при вводе в браузера или когда кто-то обращается к обновлению.
У меня была эта же проблема, и это решение работало для нас ..
Фон:
Мы размещаем несколько приложений на одном сервере. Когда мы обновим сервер, вы не поймете, где искать наш индекс в папке dist для этого конкретного приложения. Вышеупомянутая ссылка приведет вас к тому, что сработало для нас ... Надеюсь, это поможет, поскольку мы потратили немало времени на разработку решения для наших нужд.
Мы используем:
package.json
"dependencies": {
"babel-polyfill": "^6.23.0",
"ejs": "^2.5.6",
"express": "^4.15.2",
"prop-types": "^15.5.6",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^5.0.4",
"react-router": "^3.0.2",
"react-router-redux": "^4.0.8",
"redux": "^3.6.0",
"redux-persist": "^4.6.0",
"redux-thunk": "^2.2.0",
"webpack": "^2.4.1"
}
my webpack.config.js
webpack.config.js
/* eslint-disable */
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const babelPolyfill = require('babel-polyfill');
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/views/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'babel-polyfill', './app/index.js'
],
output: {
path: __dirname + '/dist/your_app_name_here',
filename: 'index_bundle.js'
},
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
query : {
presets : ["env", "react", "stage-1"]
},
exclude: /node_modules/
}]
},
plugins: [HTMLWebpackPluginConfig]
}
my index.js
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import Routes from './Routes'
import { Provider } from 'react-redux'
import { createHistory } from 'history'
import { useRouterHistory } from 'react-router'
import configureStore from './store/configureStore'
import { syncHistoryWithStore } from 'react-router-redux'
import { persistStore } from 'redux-persist'
const store = configureStore();
const browserHistory = useRouterHistory(createHistory) ({
basename: '/your_app_name_here'
})
const history = syncHistoryWithStore(browserHistory, store)
persistStore(store, {blacklist: ['routing']}, () => {
console.log('rehydration complete')
})
// persistStore(store).purge()
ReactDOM.render(
<Provider store={store}>
<div>
<Routes history={history} />
</div>
</Provider>,
document.getElementById('mount')
)
my app.js
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/dist'));
// app.use(express.static(__dirname + '/app/assets'));
app.set('views', __dirname + '/dist/your_app_name_here');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.get('/*', function (req, res) {
res.render('index');
});
app.listen(8081, function () {
console.log('MD listening on port 8081!');
});
historyApiFallback
. Что касается всех других опций, его также можно установить из CLI с флагом --history-api-fallback
.
– Marco Lazzeri
27 October 2016 в 18:28
Практическое обходное решение:
Не требуется изменений на стороне сервера.
В вашем index.html head
добавьте следующее:
<base href="/">
<!-- This must come before the css and javascripts -->
Затем при работе с сервером webpack dev используйте эту команду.
webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback
--history-api-fallback
является важной частью
Производственный стек: React, React Router v4, BrowswerRouter, Express, Nginx
1) User BrowserRouter для симпатичных URL
// app.js
import { BrowserRouter as Router } from 'react-router-dom'
const App = () {
render() {
return (
<Router>
// your routes here
</Router>
)
}
}
2) Добавьте index.html ко всем неизвестным запросы с помощью /*
// 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)
}
})
})
3) пакетный веб-пакет с webpack -p
4) запустите nodemon server.js
или node server.js
import path from 'path
, либо const path = require('path')
– Isaac Pak
10 August 2017 в 14:10
/*
) только что сэкономил мой день. Спасибо! :)
– Atlas7
22 November 2017 в 00:39
Если вы используете firebase, все, что вам нужно сделать, это убедиться, что у вас есть свойство rewrites в вашем файле firebase.json в корне вашего приложения (в разделе хостинга).
Например:
{
"hosting": {
"rewrites": [{
"source":"**",
"destination": "/index.html"
}]
}
}
Надеюсь, это избавит кого-то еще от расстройства и времени, потраченного впустую.
Счастливое кодирование ...
Дальнейшие чтения по теме:
https://firebase.google.com/docs/hosting/full-config#rewrites
Firebase CLI: «Настроить как одностраничное приложение (переписать все URL-адреса в /index.html)"
Решение для Preact с preact-router
Работает с обновлением и прямым доступом
Для тех, кто обнаруживает это через Google, вот демо истории preact-router + hash:
const { h, Component, render } = preact; /** @jsx h */
const { Router } = preactRouter;
const { createHashHistory } = History;
const App = () => (
<div>
<AddressBar />
<Router history={createHashHistory()}>
<div path="/">
<p>
all paths in preact-router are still /normal/urls.
using hash history rewrites them to /#/hash/urls
</p>
Example: <a href="/page2">page 2</a>
</div>
<div path="/page2">
<p>Page Two</p>
<a href="/">back to home</a><br/>
</div>
</Router>
</div>
);
Попробуйте добавить файл «.htaccess» в общую папку с указанным ниже кодом.
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html [L]
В случае, если кто-то ищет решение на React JS SPA с Laravel. Принятый ответ - лучшее объяснение того, почему такие проблемы происходят. Как уже объяснялось, вам необходимо настроить как клиентскую, так и серверную сторону. В своем шаблоне лезвия включите файл js в комплекте, обязательно используйте URL facade
, как это
<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');
});
Проблема заключается в том, что сначала загружается шаблон лезвия, а затем реагирует маршрутизатор. Итак, когда вы загружаете '/setting-alerts'
, он загружает html и js. Но когда вы загружаете '/setting-alerts/about'
, он сначала загружается со стороны сервера. Поскольку на стороне сервера в этом месте ничего нет, он не возвращается. Когда у вас есть этот дополнительный маршрутизатор, он загружает ту же страницу и также загружает маршрутизатор, а затем реагирует загрузчик, решает, какой компонент будет отображаться. Надеюсь, это поможет.
добавьте это в webpack.config.js
devServer: {
historyApiFallback: true
}
Для тех, кто использует IIS 10, это то, что вы должны сделать, чтобы сделать это правильно. Убедитесь, что вы используете browserHistory с этим. Что касается ссылки, я дам код для маршрутизации, но это не имеет значения, что важно для следующего шага после кода компонента ниже:
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"));
Поскольку проблема заключается в том, что IIS получает запрос от клиента браузеров, он будет интерпретировать URL-адрес так, как будто он запрашивает страницу, а затем возвращает страницу 404, так как нет доступной страницы. Выполните следующие действия:
И теперь он будет работать нормально.
Надеюсь, это поможет. : -)
Если у вас есть резерв к index.html, убедитесь, что в вашем файле index.html у вас есть это:
<script>
System.config({ baseURL: '/' });
</script>
Это может отличаться от проекта к проекту.
Я пока не использую рендеринг на стороне сервера, но я столкнулся с той же проблемой, что и OP, где ссылка, похоже, отлично работала большую часть времени, но не удалась, когда у меня был параметр.
Мой главный jsx содержит это:
<Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />
Это отлично работает для первой соответствующей ссылки, но когда: id изменения в выражениях <Link>
, вложенные в страницу подробностей этой модели, url изменяется в строке браузера, но содержимое страницы изначально не изменилось, чтобы отразить связанную модель.
Проблема заключалась в том, что я использовал props.params.id
, чтобы установить модель в componentDidMount
. Компонент только один раз монтируется, поэтому это означает, что первая модель является той, которая хранится на странице, а последующие ссылки меняют реквизиты, но оставляют страницу неизменной.
Установка модели в состоянии компонента в как componentDidMount
, так и в componentWillReceiveProps
(где он основан на следующих реквизитах) решает проблему, а содержимое страницы изменяется, чтобы отобразить желаемую модель.
props
) i.s.o. componentDidMount
, если вы хотите попробовать для серверной рендеринга. Потому что componentDidMount
вызывается только в браузере. Цель состоит в том, чтобы делать вещи с DOM, например, прикреплять слушателей событий к body
и т. Д., Которые вы не можете сделать в render
.
– Stijn de Witt
20 December 2016 в 19:38
Его довольно простой, когда вы получили, не может получить ошибку 403 после обновления компонента dom. просто добавьте эту строку в конфигурацию вашего веб-пакета, 'historyApiFallback: true'. этот savez весь мой день.
У сервера Webpack Dev есть возможность включить это. Откройте package.json
и добавьте --history-api-fallback
. Эти решения работали для меня.
webpack-dev-server
, но как я могу исправить это для сборки сборки?
– Hussain
15 August 2018 в 09:57
Если у вас есть приложение для реагирования через AWS Static S3 Hosting & amp; CloudFront
Эта проблема представила CloudFront, ответив сообщением об отказе доступа 403, потому что он ожидал / some / other / path для существования в моей папке S3, но этот путь существует только внутри маршрутизации React с реактивным маршрутизатором ,
Решение состояло в том, чтобы настроить правило «Страницы ошибок распространения». Перейдите в настройки CloudFront и выберите свой дистрибутив. Затем перейдите на вкладку «Страницы ошибок». Нажмите «Создать пользовательский ответ об ошибке» и добавьте запись для 403, так как это код состояния ошибки, который мы получаем. Задайте путь страницы ответа в /index.html и код состояния до 200. Конечный результат удивляет меня своей простотой. Страница индексирования обслуживается, но URL-адрес сохраняется в браузере, поэтому, как только приложение реагирует на загрузку, он обнаруживает путь URL-адреса и переходит на нужный маршрут.
Для пользователей React Router V4:
Если вы попытаетесь решить эту проблему с помощью техники Hash History, упомянутой в других ответах, обратите внимание, что
<Router history={hashHistory} >
не работает в V4, вместо этого используйте HashRouter
:
import { HashRouter } from 'react-router-dom'
<HashRouter>
<App/>
</HashRouter>
Ссылка: https://reacttraining.com/react-router/web/api/HashRouter
Это может решить вашу проблему
. Я также столкнулся с той же проблемой в приложении ReactJS в режиме Production. Вот 2 решение проблемы.
1. Измените историю маршрутизации на «hashHistory» вместо браузераHistory вместо
<Router history={hashHistory} >
<Route path="/home" component={Home} />
<Route path="/aboutus" component={AboutUs} />
</Router>
Теперь создайте приложение, используя команду
sudo npm run build
Затем поместите папку сборки в папку var / www / Now. Теперь приложение отлично работает с добавлением # тега в каждом URL-адресе. как
localhost / # / home localhost / # / aboutus
Решение 2: Без # тега, использующего browserHistory,
Задайте свою историю = {browserHistory} в своем Router, теперь создайте его, используя sudo npm run build.
Вам нужно создать файл «conf» для решения 404 не найденной страницы, файл conf должен быть таким.
откройте свой тип терминала следующими командами
cd / etc / apache2 / sites-available ls nano sample.conf Добавьте в него содержимое ниже.
<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>
Теперь вам нужно включить файл sample.conf с помощью следующей команды
cd /etc/apache2/sites-available
sudo a2ensite sample.conf
, то он попросит вас перезагрузить сервер Apache, перезагрузив или перезагрузив sudo-сервис apache2 или перезагрузив
, затем откройте файл localhost / создайте папку и добавьте файл .htaccess с содержимым ниже.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ / [L,QSA]
Теперь приложение работает нормально.
Примечание: измените 0.0.0.0 ip на локальный IP-адрес.
Если какие-либо сомнения относительно этого, не стесняйтесь поднять комментарий.
Надеюсь, это полезно другим.
Эта тема немного устарела и решена, но я хотел бы предложить вам простое, ясное и лучшее решение. Он работает, если вы используете веб-сервер.
Каждый веб-сервер имеет возможность перенаправить пользователя на страницу с ошибкой в случае http 404. Для решения этой проблемы вам необходимо перенаправить пользователя на страницу индекса.
Если вы используете базовый сервер Java (tomcat или любой сервер приложений Java), решение может быть следующим:
web.xml:
<?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>
Пример:
То есть, больше не нужно магии:)
const browserHistory = useRouterHistory(createHistory)({ basename: '/<appname>' });
– Chuck L
1 June 2017 в 21:40
Ответы здесь очень полезны, для меня работала настройка сервера Webpack для ожидающих маршрутов.
devServer: {
historyApiFallback: true,
contentBase: './',
hot: true
},
HistoryApiFallback - это то, что исправило эту проблему для меня. Теперь маршрутизация работает правильно, и я могу обновить страницу или ввести URL-адрес напрямую. Не нужно беспокоиться о работе вокруг вашего узла. Этот ответ, очевидно, работает только в том случае, если вы используете webpack.
EDIT: см. Мой ответ здесь для более подробной причины, почему это необходимо: https://stackoverflow.com/a/37622953/ 5217568
historyApiFallback
. Что касается всех других опций, его также можно установить из CLI с флагом --history-api-fallback
.
– Marco Lazzeri
27 October 2016 в 18:28