I am using vue-router on a multipage app; we are adding history mode because our requirements insist our urls not contain special characters (#) and want to ensure from within our frontend code that we are always prepending our clientside routes with /v/. (to avoid having to update all our routes in the whole app, and to centralize this functionality).
I want to add a route similar to:
routes: [
// add `v/` to paths that don't start with `v/`
{
path: `(^\/(?!v))*`,
redirect: to => `/v/${to}`
},
]
Based on using regex inside path-to-regexp, but I'm not entirely clear from their documentation how to properly pass in a whole route as a regex (or is it possible?), especially without getting caught in a redirect loop.
I was able to use 2 redirects to achieve what I needed (in this case falling back to '/' as a sort of 404.
// Fallback to baseRoute for prefixed unmatched routes
{ path: `${prefix}/*`, redirect: '/' },
// Fallback to baseRoute for unprefixed, unmatched routes (try again with prefix)
{ path: `*`, redirect: to => prefix + to.path }
(An interesting gotcha is that in a redirect function the to value remains unchanged if you get redirected, so I originally had an infinite loop. with to => to.path.startsWith(prefix) ? '/' : prefix + to.path)
Related
I am having an issue in my nuxtjs application refreshing the page (F5).
Let's say im in this page https://example.com/foo/bar (which equals to https://example.com/foo/bar/index.html) and I press the refresh button the page doesn't reload after some time I get a this site can't be reached error.
But when I put a slash / at the end it reloads perfectly.
Also, I cannot access the page directly without a slash at the end or /index.html and when I do it changes to https://example.com/foo/bar.
Any idea on how to fix this?
I do not want to use router: { trailingSlash: false }, because I read that is going to affect my SEO.
I also added this: NuxtJS Static generated HTML page does not load Javascript when calling /index.html but it did not solved this issue tho it solved another one I had.
my nuxt-config.js:
router: {
//https://stackoverflow.com/questions/63719727/nuxtjs-static-generated-html-page-does-not-load-javascript-when-calling-index-h
extendRoutes(routes) {
routes.forEach((route) => {
// When options.generate.subFolders is true (default)
const alias = route.path.length > 1 ? `${route.path}/index.html` : '/index.html'
// When options.generate.subFolders is false
// const normalizedRoute = route.path.replace(/\/$/, '') // Remove trailing slashes if they exist
// const alias =
// route.path.length > 1 ? `${normalizedRoute}.html` : '/index.html'
route.alias = alias
})
},
},
Update 21/07/2021
I added the
router: { trailingSlash: true } and also install the #nuxtjs/redirect-module
['#nuxtjs/redirect-module', {
redirect: [
{
from: '^.*(?<!/)$',
to: (from, req) => req.url + '/',
statusCode: 301
}]
}]
but the issue still persists. Locally it works fine but when deployed in the server it does not.
I have two custom page types that use dynamic routing, queried from Prismic CMS, service_page and about_page. I'm running into a problem in my express server custom routing however - if my servicePage route is listed first, the aboutPage wont render. But if its vice versa, the servicePage won't route but my aboutPages will. Is there a way to have two custom types with dynamic routes? I understand I can add a prefix to them (services/:uid or about/:uid) but I'd really rather avoid that for company purposes.
server.get('/:uid', (req, res) => {
const nextJsPage = '/servicePage';
const queryParams = { uid: req.params.uid };
app.render(req, res, nextJsPage, queryParams);
});
server.get('/:uid', (req, res) => {
const nextJsPage = '/aboutPage';
const queryParams = { uid: req.params.uid };
app.render(req, res, nextJsPage, queryParams);
});
What is your purpose?
When using routing in general the first listed url that matches the url you requested will be displayed. You can't expect any other behavior.
I don't think you can use Regex here if there is a difference between the ids (such as 9 digits vs. 2 digits for example), but you can try searching about it. Otherwise, you must use a prefix.
I am currently trying to pass my password reset generated token inside my unprotected route but whenever I execute my GET request, I receive an 401 Unauthorized request.
I've tried including the package Path-to-RegExp and constructing a separate array route but it didn't work:
let tokens = [];
const unprotected = [
pathToRegexp('/user/reset/:token', tokens),
];
My password-reset token is generated in a separated service and called in a controller:
const token = crypto.randomBytes(20).toString('hex');
user.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 360000,
});
Here is how I've structured my expressJwt with unless:
app.use(expressJwt({
secret: process.env.SECRET_BEARER,
getToken: req => {
MY TOKEN AUTHORISATION CODE IS PLACED HERE.
}
}).unless({ path: ['/images/', '/user/password-reset', unprotected ]}));
My issue is that whenever I try to create a unauthenticated route such as .unless({path: ['/images/', '/user/password-reset', '/user/reset/:token' ]})); the route /user/reset/:token is only parsed as a string a the value of :token is not actually passed.
I've read some similar questions about passing it with regex or functions but I couldn't figure it out myself. This and this question have been particularly useful on how to approach the problem.
You can pass a regex to unless, which you may have already realized since you tried to use Path-to-RegExp. You could also just try to write the regex yourself and pass it directly to unless. In your case your unless would look like this:
.unless({ path: [/\/images\//, /\/user\/password-reset\//, /^\/user\/reset\/[a-z0-9_-]*/]}));
EDIT: this SO answer suggest that you cannot combine regex and strings in the same array, so I've converted all paths to regex expressions.
You have an array within an array for the value of path passed into unless.
Change:
}).unless({ path: ['/images/', '/user/password-reset', unprotected ]}));
To:
}).unless({ path: unprotected }));
And change unprotected to include the other paths:
const unprotected = [
'/images/',
'/user/password-reset',
pathToRegexp('/user/reset/:token', tokens),
];
Ensure you test with a path that includes a token e.g:
/user/reset/123-some-real-looking-value
I'm trying to create a custom route in Sails and according to their documentation, if I add the following in config/routes.js:
'post /api/signin': 'AuthController.index',
The request would be dealt with by the index action in the AuthController but that doesn't seems to work at all. When I try the /api/login in Postman, I get nothing back.
Please note that I've added restPrefix: '/api' in my config/blueprints.js. Please note I'm using Sails 0.12.x
What am I missing here?
Since you are pointing to a controller with method index on it, you need to add it to your controllers and send a JSON response from there, (since you are using post). here is a simple example
config/routes.js
'post /api/signin': 'AuthController.index',
api/controllers/AuthController.js
module.exports = {
index: function(req, res) {
var id = req.param('id');
if(!id) {
return res.json(400, { error: 'invalid company name or token'});
}
/* validate login..*/
res.json(200, {data: "success"};
}
}
Update
Since you already have the above its probably caused by the blueprints you have.
Blueprint shortcut routes
Shortcut routes are activated by default in new Sails apps, and can be
turned off by setting sails.config.blueprints.shortcuts to false
typically in /config/blueprints.js.
Sails creates shortcut routes for any controller/model pair with the
same identity. Note that the same action is executed for similar
RESTful/shortcut routes. For example, the POST /user and GET
/user/create routes that Sails creates when it loads
api/controllers/UserController.js and api/models/User.js will
respond by running the same code (even if you override the blueprint
action)
with that being said from sails blueprint documentation, maybe turning off shortcuts and remove the prefix you've added.
possibly the shortcuts are looking elsewhere other than your controllers thus returning 404.
the prefix is being added to your blueprint connected route, hence you need /api/api/signin to access it?
Note
I am unable to replicate your issue on my computer as its working fine over here. but i have all blueprint settings turned off.
module.exports.blueprints = {
actions: false,
rest: false,
shortcuts: false,
// prefix: '',
pluralize: false,
populate: false,
autoWatch: false,
};
I'm working on a website where we are using 3rd Party web services to return dynamic content and using javascript to parse and display that data from to the page. We are already using backbone in a couple places on the site to post data to web services so I had the thought of trying to use Backbone's router to run specific functions based on the page url and grabbing the query because we are hashing the queries to the url of the page.
For example: global-site-search.html#query
This is the router code I have to this point:
var Router = Backbone.Router.extend({
routes : {
'' : 'indexRoute',
'global-site-search.html(:query)' : 'getSearchResults'
},
indexRoute: function(query) {
console.log("indexRoute");
},
getSearchResults: function(query) {
console.log("getSearchResults with query", query);
}
});
var WaRouter = new Router();
Backbone.history.start({
pushState: true,
root: '/'
});
But when I hit the page with a url like global-site-search.html#query the query value returns null. Has anyone tried this before or am I trying to extend Backbone's router to far in handling this?
Is global-site-search.html from your server?, if yes then the config for router should be
':query' : 'getSearchResults'
If no, then you can't do that, because Backbone.Router uses the hash part of the current page URL to track pages. And since global-site-search.html is not containing any backbone code, it can't do anything. It is possible only if you somehow can inject your router code into global-site-search.html which is illegal in this case
Updated: this should allow you to search with this route ':query' : 'getSearchResults'
Backbone.history.start({
pushState: true,
root: window.location.pathname
});
When using router, you need to set the correct root, so using window.location.pathname is the easiest way to do that. Also, according to Backbone documentation
and if a hash URL is visited by a pushState-capable browser, it will be transparently upgraded to the true URL. Note that using real URLs requires your web server to be able to correctly render those pages, so back-end changes are required as well. For example, if you have a route of /documents/100`
Since you are not having any real back-end to handle pushState, I suggest that you turn it off