在我的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。
答案 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;