44

我有一个按钮,它正在执行获取我的页面并向查询字符串添加过滤器。我的代码将该过滤器应用于网格,但用户可以删除/编辑该过滤器。因为他们可以看到在网格中应用了哪些过滤器,所以我想在?filter=blah显示页面时从查询字符串中删除 。

如果在页面上并且 URL?filter=columnA显示最初是正确的,则可能会令人困惑,但用户删除了该过滤器并应用了一个新过滤器,columnB但查询字符串仍然显示?filter-columnA. 网格可以处理更改过滤器而无需回发。

我怎样才能做到这一点?如果您无法删除/更新查询字符串,是否可以解析它,然后在没有查询字符串的情况下重定向到主页?将过滤器保存到 var 过滤器后,查询字符串中就不再需要它了。

这是显示页面的代码:

exports.show = function(req, res) {
    var filter = req.query.filter;
    if (filter === null || filter === "") {
        filter = "n/a";
    }
    
    res.render("somepage.jade", {
            locals: {
                title: "somepage",
                filter: filter
            }
    });

};
4

10 回答 10

64

用于url.parse()获取地址的组成部分,即req.url. 没有查询字符串的 url 存储在pathname属性中。

使用 express'redirect发送新的页面地址。

const url = require('url'); // built-in utility
res.redirect(url.parse(req.url).pathname);

的节点文档url

于 2013-10-28T15:29:00.020 回答
28

不要使用模块来做这样的事情:

res.redirect( req.originalUrl.split("?").shift() );
于 2015-08-20T12:54:17.460 回答
18

Express 4.x+ 答案:
res.redirect(req.path)

于 2016-08-09T22:36:12.687 回答
6
// load built-in utilities for URL resolution and parsing
var url = require('url');

function removeQueryString(url){

  // split url into distinct parts
  // (full list: https://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost)
  var obj = url.parse(url);

  // remove the querystring
  obj.search = obj.query = "";

  // reassemble the url
  return url.format(obj);

}
于 2016-04-16T17:32:55.863 回答
5

利用req.path

如果您的端点是http://<your-domain>.com/hello/there?name=john...

然后req.path=/hello/there


文档:https ://expressjs.com/en/api.html#req.path

于 2019-04-04T17:52:46.973 回答
4

完整的 url 存储在req.url您的案例中,使用 node.js 的url.parse()提取部分。获取路径并发送 Location 标头res.set()用于重定向到没有查询字符串的 URL。

var url = require('url');
res.set('Location', url.parse(req.url).pathname);
于 2013-01-05T00:19:21.823 回答
4

通用 Node.js 解决方案

> new URL('https://example.com/admin/new?foo=bar').pathname;
'/admin/new'

如果您还想包括原点:

> const url = require('url');
> url.format(new URL('https://example.com/admin/new?foo=bar'), {search: false});
'https://example.com/admin/new'

Express.js 解决方案

其他答案包括使用req.url/ req.originalUrl/ req.path/的各种组合req.baseUrl。使用哪一个取决于上下文。如果您在app.METHOD函数中或者从中间件或嵌套路由器内部访问它们,这些属性的行为会有所不同。

概括:

  • usingreq.originalUrl应该是最通用的,但您需要自己解析路径名(见上文)。
  • 使用req.path是最直接的,但您必须确保您不在中间件/嵌套路由器中。

当您在app.METHOD函数内部时:

// GET 'http://example.com/admin/new?foo=bar'
app.get('/admin/new', (req, res) => {
    console.dir(req.originalUrl); // '/admin/new?foo=bar'
    console.dir(req.url); // '/admin/new?foo=bar
    console.dir(req.baseUrl); // ''
    console.dir(req.path); // '/admin/new'
    return res.status(200).send('All engines running!');
});

当您在中间件(或嵌套路由器)中时:

// GET 'http://example.com/admin/new?foo=bar'
app.use('/admin', (req, res, next) => {
    console.dir(req.originalUrl); // '/admin/new?foo=bar'
    console.dir(req.url); // '/new?foo=bar'
    console.dir(req.baseUrl); // '/admin'
    console.dir(req.path); // '/new'
    next();
});
于 2021-06-06T12:42:46.180 回答
3

为了避免通过强制重定向重新加载页面,我将以下内容添加到<head>我的 .ejs 文件的部分:

<script type="text/javascript">
    var uri = window.location.toString();
    if (uri.indexOf("?") > 0) {
        var clean_uri = uri.substring(0, uri.indexOf("?"));
        window.history.replaceState({}, document.title, clean_uri);
    }
</script>

来源:http ://atodorov.org/blog/2013/01/28/remove-query-string-with-javascript-and-html5/

于 2017-06-20T09:02:08.463 回答
1

使用此方法从 URL 中删除特定的查询参数。

/**
     * remove query parameters from actual url
     * @param {*} params paramerters to be remove, e.g ['foo', 'bar'] 
     * @param {*} url actual url 
     */
    function removeQueryParam(parameters = [], url) {
        try {
            var urlParts = url.split('?');
            var params = new URLSearchParams(urlParts[1]);
            parameters.forEach(param => {
                params.delete(param);
            })
            return urlParts[0] + '?' + params.toString();
        } catch (err) {
            console.log(err);
            return url;
        }
    }

    console.log(removeQueryParam(["foo"], "/foo?foo=foo&bar=bar"));

上面的例子将返回/foo?bar=bar

于 2020-12-11T08:07:23.627 回答
0

我有一个类似的问题,我处理它的方法是在部分。但是,为了避免在我向后或向前移动时出现不一致,我需要添加一个onbeforeunload事件侦听器。这种方法的好处是它避免了重定向。

    // 将原始 url 存储在本地存储中
    window.localStorage.setItem('specifiedKey', window.location.href);

    // 清除字符串的查询参数并在历史 API 中替换它
    const cleanUrl = location.href.match(/^.+(?=\?)/g);
    window.history.replaceState(null, null, (cleanUrl ? cleanUrl[0] : location.href));

    // 在窗口重新加载之前更新历史记录
    window.onbeforeunload = () => {
    window.history.replaceState(null, null, window.localStorage.getItem('specifiedKey'));
        }

我想象的唯一问题是浏览器不兼容,JavaScript 引擎无法支持正则表达式后视运算符。这可以使用 .split('?')[0] 轻松解决

于 2018-12-25T14:39:09.943 回答