如何使用多个问号格式化网址并确保使用最后一个查询字符串

时间:2016-07-06 21:26:52

标签: javascript node.js url query-string

在我的node.js应用程序中,我正在使用接受调用的API,如下所示

http://myapi.com/action?url= https://www.test.com/play?action=jump

然后根据传递给URL参数的参数(例如''action = jump'),API返回一个特定的响应。

我遇到的问题是,在某些情况下,发送到API的网址可能已经有一个带有查询字符串的问号(?song = portrait)

http://myapi.com/action?url= https://www.test.com/play?song=portrait?action=jump

在这种情况下,API会发回错误的响应,因为它使用了查询字符串中的第一个问号参数。示例?song=portrait

如果不修改API,我如何确保API在最后读取参数 - 例如 - action=jump

有没有办法逃避第一个问号,但保留有效的网址,或者如何使用url.format()url.parse()来解决此问题

我忘了添加我已经编码传递给URL参数的URL。

5 个答案:

答案 0 :(得分:3)

考虑使用url.parse()/url.format()在node.js中正确处理网址。

您可以尝试:

 angular.module('Busslip').factory('DB', function($q, DB_CONFIG) 
 {
    var self = this;
    self.db = null;

    self.init = function() {
         //Use  in production
         alert('start');
        self.db = window.sqlitePlugin.openDatabase({name: DB_CONFIG.name});
        alert('dbalert END');
        alert(DB_CONFIG.name); //// here i get DB in alert 
        //self.db  = window.openDatabase(DB_CONFIG.name);
        //self.db = window.openDatabase(DB_CONFIG.name, '1.0', 'database', -1);
        //self.db = window.sqlitePlugin.o  penDatabase(DB_CONFIG.name, '2');
      alert('dbalert END');
        angular.forEach(DB_CONFIG.tables, function(table) {
            var columns = [];

            angular.forEach(table.columns, function(column) {
                columns.push(column.name + ' ' + column.type);
            });

            var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
            self.query(query);
            console.log('Table ' + table.name + ' initialized');
        });
    };

    self.query = function(query, bindings) {
        bindings = typeof bindings !== 'undefined' ? bindings : [];
        var deferred = $q.defer();

        self.db.transaction(function(transaction) {
            transaction.executeSql(query, bindings, function(transaction, result) {
                deferred.resolve(result);
            }, function(transaction, error) {
                deferred.reject(error);
            });
        });

        return deferred.promise;
    };

    self.fetchAll = function(result) {
        var output = [];

        for (var i = 0; i < result.rows.length; i++) {
            output.push(result.rows.item(i));
        }

        return output;
    };

    self.fetch = function(result) {
        return result.rows.item(0);
    };

    return self;
})

它将构建一个正确的网址:var url = require('url'); , apiurl = 'http://myapi.com/action'; , urlObject = url.parse(apiurl); // Add query string parameters urlObject.query = { action: 'jump', url: 'https://www.test.com/play?song=portrait' }; // Generate valid url var urlString = url.format(urlObject); console.log(urlString);

另外,请记住第一个问号are treated as literal之后的任何其他问号。

答案 1 :(得分:1)

您应该使用encodeURIComponent(在浏览器和节点中工作)。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

答案 2 :(得分:1)

而不是添加?action=jump您希望将&action=jump添加到此网址:https://www.test.com/play%3F

请注意%3F - 部分,它是一个经过编码的?

这不起作用,因为它只是将该部分作为另一个参数添加到http://myapi.com/action - url。

我知道您已经对您的网址进行了编码,但它不会对&进行编码,因此我们必须手动执行此操作。

您可以在添加参数时将&更改为%26来解决此问题。

示例:

http://myapi.com/action?url=https://www.test.com/play%3Fsong=portrait%26action=jump

在服务器端,您希望使用decodeURIComponent(req.query.url)%26解析回&

这样,您就会拥有一个完整正确的网址:

https://www.test.com/play?song=portrait&action=jump

使用此字符串,您可以使用此主题中的函数:How can I get query string values in JavaScript?

function getParameterByName(name, url) {
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

并将其命名为:

getParameterByName('action', 'https://www.test.com/play?song=portrait&action=jump')

这将返回jump

现在你可以解析你的网址并提取参数&#34; action&#34;始终确保您获得正确的参数,无视位置。

答案 3 :(得分:0)

也许我过于简单了,但你不能使用lastIndexOf()

var url = 'http://myapi.com/action?url= https://www.test.com/play?song=portrait?action=jump';
var params = url.slice(url.lastIndexOf('?')+1);
console.log(params) // action=jump

答案 4 :(得分:0)

当您使用查询字符串值构建url时,首先通过传递查询字符串值来调用 encodeURIComponent 方法,然后构建URL。

例如:
var encodedURLComp =&#34; http://myapi.com/action?url =&#34; + window.encodeURIComponent(&#34; https://www.test.com/play?song=portrait?action=jump&#34;); 警报(encodedURLComp);

它编码以下文字@#$&amp; =:/,;?+&#39;