มีวิธีใดในการป้องกันไม่ให้/#/
แสดงในแถบที่อยู่ของเบราว์เซอร์เมื่อใช้ react-router? นั่นคือด้วย ReactJS เช่นการคลิกลิงก์ที่จะไปแสดงให้เห็นเส้นทางใหม่หรือlocalhost:3000/#/
localhost:3000/#/about
ขึ้นอยู่กับเส้นทาง
มีวิธีใดในการป้องกันไม่ให้/#/
แสดงในแถบที่อยู่ของเบราว์เซอร์เมื่อใช้ react-router? นั่นคือด้วย ReactJS เช่นการคลิกลิงก์ที่จะไปแสดงให้เห็นเส้นทางใหม่หรือlocalhost:3000/#/
localhost:3000/#/about
ขึ้นอยู่กับเส้นทาง
คำตอบ:
สำหรับรุ่นที่ 1, 2 และ 3 ของการตอบสนองเตอร์, วิธีที่ถูกต้องในการตั้งค่าเส้นทางไปโครงการทำแผนที่ URL ที่เป็นโดยผ่านการดำเนินงานประวัติศาสตร์เข้าไปในพารามิเตอร์ของhistory
<Router>
จากเอกสารประวัติ :
โดยสรุปประวัติจะรู้วิธีฟังแถบที่อยู่ของเบราว์เซอร์สำหรับการเปลี่ยนแปลงและแยกวิเคราะห์ URL เป็นวัตถุตำแหน่งที่เราเตอร์สามารถใช้เพื่อจับคู่เส้นทางและแสดงชุดส่วนประกอบที่ถูกต้อง
ใน react-router 2 และ 3 รหัสการกำหนดเส้นทางของคุณจะมีลักษณะดังนี้:
import { browserHistory } from 'react-router'
ReactDOM.render ((
<Router history={browserHistory} >
...
</Router>
), document.body);
ในเวอร์ชัน 1.x คุณจะใช้สิ่งต่อไปนี้แทน:
import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render ((
<Router history={createBrowserHistory()} >
...
</Router>
), document.body);
ที่มา: คู่มือการอัปเกรดเวอร์ชัน 2.0
สำหรับ react-router เวอร์ชัน 4 ที่กำลังจะมานั้นไวยากรณ์ได้เปลี่ยนไปอย่างมากและจำเป็นต้องใช้BrowserRouter
เป็นแท็กรูทของเราเตอร์
import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render ((
<BrowserRouter>
...
<BrowserRouter>
), document.body);
history
เป็นแพ็คเกจแบบสแตนด์อะโลนที่คุณจะต้องติดตั้ง
browserHistory
ใน v2.x: import { browserHistory } from 'react-router' <Router history={browserHistory} />
ตรวจสอบคู่มือการอัปเกรด react-router
hashHistory
มีวิธีกำจัดพารามิเตอร์แบบสอบถามนี้ในตอนท้ายหรือไม่? http://localhost:8080/#/dashboard?_k=yqwtyu
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
สำหรับเวอร์ชันปัจจุบัน 0.11 และไปข้างหน้าคุณจะต้องเพิ่มการRouter.HistoryLocation
เลิกใช้งานแล้ว ดูคู่มือการอัพเกรดสำหรับการใช้งาน HistoryLocation 0.12.xRouter.run()
<Routes>
หากคุณไม่ต้องการรองรับ IE8 คุณสามารถใช้ประวัติเบราว์เซอร์และเราเตอร์ตอบสนองจะใช้ window.pushState
แทนการตั้งค่าแฮช
วิธีการทำสิ่งนี้ขึ้นอยู่กับรุ่นของ React Router ที่คุณใช้:
<Routes location="history">
ทุกอย่างทำงานได้ดีจนกว่าคุณจะรีเฟรชเบราว์เซอร์เมื่ออยู่บนเส้นทางเช่นlocalhost:3000/about
นั้นฉันจะได้รับข้อผิดพลาด 404 คาดว่าฉันกำลังใช้อยู่python -m SimpleHTTPServer 3000
?
/about
โหลดหน้ารูทของคุณได้/
จริง มิฉะนั้นเซิร์ฟเวอร์ของคุณจะพยายามค้นหาเส้นทางที่ตรงกัน/about
และไม่พบอะไรเลย (404) ฉันไม่ได้ใช้ python เป็นการส่วนตัว แต่คุณมักจะพบเส้นทางด้วยตนเองสำหรับ/*
หรือ/.*
-> ใช้/
งานได้ - หรืออาจเป็นสิ่งที่เรียกว่าhtml5Mode
URL ในการตั้งค่าเซิร์ฟเวอร์ของคุณ
คุณสามารถใช้. htaccess เพื่อทำสิ่งนี้ได้ โดยปกติเบราว์เซอร์ต้องการตัวคั่นสตริงคิวรี?
หรือ#
กำหนดตำแหน่งที่สตริงเคียวรีเริ่มต้นและพา ธ ไดเร็กทอรีสิ้นสุด ผลลัพธ์ที่เราต้องการคือดังนั้นเราจึงจำเป็นที่จะจับปัญหาก่อนที่การค้นหาเว็บเซิร์ฟเวอร์สำหรับไดเรกทอรีมันคิดว่าเราถามหาwww.mysite.com/dir
/dir
ดังนั้นเราจึงวาง.htaccess
ไฟล์ไว้ในรูทของโปรเจ็กต์
# Setting up apache options
AddDefaultCharset utf-8
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine on
# Setting up apache options (Godaddy specific)
#DirectoryIndex index.php
#RewriteBase /
# Defining the rewrite rules
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.html
จากนั้นคุณจะได้รับพารามิเตอร์เคียวรีด้วย window.location.pathname
จากนั้นคุณสามารถหลีกเลี่ยงการใช้เส้นทางการตอบสนองได้หากคุณต้องการและเพียงแค่ปรับเปลี่ยน url และประวัติเบราว์เซอร์หากคุณต้องการเช่นกัน หวังว่านี่จะช่วยใครสักคน ...
ติดตั้งแพ็คเกจประวัติ
npm install history --save
นำเข้า createHistory และ useBasename ถัดไปจากประวัติ
import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
basename: '/root'
});
หาก url แอปของคุณคือ www.example.com/myApp ดังนั้น / root ควรเป็น / myApp
ส่งผ่านตัวแปรประวัติไปยังเราเตอร์
render((
<Router history={history}>
...
</Router>
), document.getElementById('example'));
ตอนนี้สำหรับแท็กลิงก์ทั้งหมดของคุณจะต่อท้าย "/" ไว้หน้าเส้นทางทั้งหมด
<Link to="/somewhere">somewhere</Link>
แรงบันดาลใจของโซลูชันมาจากReact-Router Example ซึ่งน่าเสียดายที่ไม่ได้รับการบันทึกไว้อย่างถูกต้องใน API
อีกวิธีหนึ่งในการจัดการสิ่งที่จะแสดงหลังจากแฮช (ดังนั้นหากคุณไม่ได้ใช้ pushState!) คือการสร้าง CustomLocation ของคุณและโหลดที่การสร้าง ReactRouter
ตัวอย่างเช่นหากคุณต้องการมี hashbang url (ดังนั้นจึงมี #!) เพื่อให้สอดคล้องกับข้อกำหนดของ Google สำหรับการรวบรวมข้อมูลคุณสามารถสร้างไฟล์ HashbangLocation.js ซึ่งส่วนใหญ่จะคัดลอก HashLocation ดั้งเดิมเช่น:
'use strict';
var LocationActions = require('../../node_modules/react-router/lib/actions/LocationActions');
var History = require('../../node_modules/react-router/lib/History');
var _listeners = [];
var _isListening = false;
var _actionType;
function notifyChange(type) {
if (type === LocationActions.PUSH) History.length += 1;
var change = {
path: HashbangLocation.getCurrentPath(),
type: type
};
_listeners.forEach(function (listener) {
listener.call(HashbangLocation, change);
});
}
function slashToHashbang(path) {
return "!" + path.replace(/^\//, '');
}
function ensureSlash() {
var path = HashbangLocation.getCurrentPath();
if (path.charAt(0) === '/') {
return true;
}HashbangLocation.replace('/' + path);
return false;
}
function onHashChange() {
if (ensureSlash()) {
// If we don't have an _actionType then all we know is the hash
// changed. It was probably caused by the user clicking the Back
// button, but may have also been the Forward button or manual
// manipulation. So just guess 'pop'.
var curActionType = _actionType;
_actionType = null;
notifyChange(curActionType || LocationActions.POP);
}
}
/**
* A Location that uses `window.location.hash`.
*/
var HashbangLocation = {
addChangeListener: function addChangeListener(listener) {
_listeners.push(listener);
// Do this BEFORE listening for hashchange.
ensureSlash();
if (!_isListening) {
if (window.addEventListener) {
window.addEventListener('hashchange', onHashChange, false);
} else {
window.attachEvent('onhashchange', onHashChange);
}
_isListening = true;
}
},
removeChangeListener: function removeChangeListener(listener) {
_listeners = _listeners.filter(function (l) {
return l !== listener;
});
if (_listeners.length === 0) {
if (window.removeEventListener) {
window.removeEventListener('hashchange', onHashChange, false);
} else {
window.removeEvent('onhashchange', onHashChange);
}
_isListening = false;
}
},
push: function push(path) {
_actionType = LocationActions.PUSH;
window.location.hash = slashToHashbang(path);
},
replace: function replace(path) {
_actionType = LocationActions.REPLACE;
window.location.replace(window.location.pathname + window.location.search + '#' + slashToHashbang(path));
},
pop: function pop() {
_actionType = LocationActions.POP;
History.back();
},
getCurrentPath: function getCurrentPath() {
return decodeURI(
// We can't use window.location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
"/" + (window.location.href.split('#!')[1] || ''));
},
toString: function toString() {
return '<HashbangLocation>';
}
};
module.exports = HashbangLocation;
สังเกตฟังก์ชันslashToHashbang
จากนั้นคุณก็ต้องทำ
ReactRouter.create({location: HashbangLocation})
และนั่นแหล่ะ :-)
HashHistory
BrowserHistory
ดูคำถาม SO นี้ที่ฉันให้ข้อมูลพื้นฐานมากมายเกี่ยวกับเรื่องนี้