Давненько я не писал сухой технической статьи.За последние два дня я только что наткнулся на реализацию функции, которая раньше меня особо не волновала--Внешний интерфейс получает параметры, переданные URL-адресом.
Ведь она обычно обрабатывается в фоновом режиме.Потеряв пучок волос,подумай об этом или выпиши и поделись с собой.Если столкнешься в будущем,тоже есть ссылка.
Нетрудно просто получить некоторые обычные строки.Ключ в том, чтобы иметь некоторые беспорядочные требования.Зачем передавать одно и то же имя параметра несколько раз, передавать массив. Я много писал об этом
Сначала поговорим об идеях.Если вы читаете эту статью, чтобы решить проблему и использовать код напрямую, просто посмотрите на последнюю реализацию кода и как ее использовать.
Анализ проблем с рамочным мышлением
дает вам URL-адрес, подобный следующему:
Преобразуйте параметры, переданные в URL-адресе, вobjectобъекта, чтобы нам было удобнее использовать параметры
Я много раз подчеркивал рамочное мышление, Теперь, когда мы столкнулись с этой проблемой, давайте возьмем фреймворк для анализа, как мы можем решить ее быстро
Во-первых, понять нашуКакова цель? Цель очень проста, получить параметры, переданные в URL-адресе, и разобрать их на объекты.
Затем проанализируйтечто мы знаем сейчас? Есть строка URL
Разберем еще раз, если переданные параметры получены из URL, то естьЧто мы должны сделать, чтобы достичь нашей цели?
Обычно мы знаем характеристики URL, который является первым?Все следующие строки являются передаваемыми параметрами, ноЕсть особый случай, пожалуйста, не забывайте, за URL иногда будет следовать#,а также#Следующее содержимое — это не параметр, который мы хотим передать, а идентификатор местоположения веб-страницы.
Если URL-адрес содержит#,Нам просто нужно разобрать?прибыть#Строка между, если не включено, то первое?В конце концов, контент — это то, что нам нужно для анализа
Вы можете подумать, что я говорю чепуху, что такое очевидное может понять любой, кто не идиот.
Конечно, я знаю, пока ни один идиот не может понять,Но почему я должен это подчеркивать? Поскольку мы хотим решать проблемы быстро, у нас должно быть структурное мышление, которое также можно назвать инженерным мышлением.
Вы скажете, что такую простую задачу нужно анализировать таким образом? Мы знаем это с первого взгляда, вы режете цыплят бычьим ножом
Хотя это бычий нож для убийства кур, ноЕсли вы хотите развить собственное инженерное мышление, вы должны целенаправленно тренироваться до тех пор, пока оно не будет у вас под рукой.
Что ж, после анализа мы будем реализовывать его поэтапно в соответствии с вышеизложенными идеями, у нас могут возникнуть другие проблемы во время внедрения, и мы будем анализировать и решать их в это время.
Ведь каким бы великим инженером он ни был, он не будет думать обо всем, прежде чем начать.Будьте максимально вдумчивы, прежде чем внедрять его, и быстро итеративно обновляйте, когда сталкиваетесь с проблемами.
Процесс получения JS параметров URL
Сначала используйте JS, чтобы получить URL. Если функция передает URL, используйте параметр. Если параметры не переданы, используется URL текущей страницы.
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
если следующая строка существует#, мы должны#Завершающая строка удаляется, потому что#Следующий контент — это не параметр, который нам нужно получить, а идентификатор местоположения веб-страницы
queryString = queryString.split('#')[0];
Ну а после удаления всех мешающих частей можно со спокойной душой приступать к разбору параметров, для начала разделим переданные параметры на массивы
var arr = queryString.split('&');
Теперь мы можем получить массив строк
['product=shirt', 'color=blue', 'newuser', 'size=m']
После разбиения строки на массив мы сохраняем все наши параметры, создавая объект
var obj = {};
Мы можем перебрать массив с помощьюarr, разбить его на пары ключ-значение. сделать эту строкуkey:valueОбъект
var a = arr[i].split('=');
Следующим шагом является установка каждой переменнойkeyприсвоить соответствующее значениеvalue, если мы получимvalueне является правильным параметром, мы просто используемtrueКонечно, чтобы указать, что имя параметра существует, вы также можете изменить его в соответствии с вашей реальной ситуацией.
var paramName = a[0];
var paramValue = typeof(a[1]) === 'undefined' ? true : a[1];
я прямо здесьundefinedотмечено, если этоNaN, я просто рассматривал это как строку
Здесь есть небольшая яма, чтобы напомнить, когда мы вызываем функцию для получения значения объекта, если передан URLkeyДля верхнего регистра мы пишем нижний регистр, когда берем объект, тогда результатundefined
Например, URL-адресhttp://NaoNao.com/?NamE=NaoNao, если обработка case не производится, при вызове объекта для получения значенияgetAllUrlParams().NamEчтобы получить значениеNaoNao, если он обрабатывается, нам нужно только писать все строчные/прописные буквы при его использовании, напримерgetAllUrlParams().name
Я преобразовал их все в нижний регистр здесь.Если вам требуется различать верхний и нижний регистр, тогда просто удалите этот код.
paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();
Далее мы будем иметь дело с тем, что мы получилиparamValue,Эти аргументы могут быть индексированными массивами, неиндексированными массивами или обычными строками.
Если это индексированный массив, мы должныparamValueПреобразуйте его в массив и поместите значение, соответствующее индексу, в позицию, соответствующую индексу.
Если это неиндексированный массив, мы будемparamValueположить в массив
если это обычная строка, нам понадобится для нашего объектаobjСоздайте обычное свойство и присвойте ему значение.
если ключ уже существует, то мы преобразуем существующийparamValueотkey:valueПреобразовать в массив и поместить его в массив
Возьмите несколько реальных случаев и почувствуйте, что мы собираемся делать.
// 索引数组
getAllUrlParams('http://NaoNao.com/?colors[0]=red&colors[2]=green&colors[6]=blue');
// { "colors": [ "red", null, "green", null, null, null, "blue" ] }
// 非索引数组
getAllUrlParams('http://NaoNao.com/?colors[]=red&colors[]=green&colors[]=blue');
// { "colors": [ "red", "green", "blue" ] }
// 多次传递同一个key
getAllUrlParams('http://NaoNao.com/?colors=red&colors=green&colors=blue');
// { "colors": [ "red", "green", "blue" ] }
// 传递了key,但是没传value
getAllUrlParams('http://NaoNao.com/?product=shirt&color=blue&newuser&size=m');
// { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }
Я использую регулярные выражения, чтобы сделать это суждение, поэтому я не буду здесь объяснять регулярные выражения. . . В конце концов, объяснение слишком длинное, так что попробуйте его прочитать, если сможете понять.
Что предстоит разобрать каждому регулярному, примеры написаны в комментариях,Большинство студентов, которые немного знакомы с регулярными выражениями, могут их понять.
Соответствующий код реализован следующим образом:
// 如果paramName以方括号结束, e.g. colors[] or colors[2]
if (paramName.match(/\[(\d+)?\]$/)) {
// 如果paramName不存在,则创建key
var key = paramName.replace(/\[(\d+)?\]/, '');
if (!obj[key]) obj[key] = [];
// 如果是索引数组 e.g. colors[2]
if (paramName.match(/\[\d+\]$/)) {
// 获取索引值并在对应的位置添加值
var index = /\[(\d+)\]/.exec(paramName)[1];
obj[key][index] = paramValue;
} else {
// 如果是其它的类型,也放到数组中
obj[key].push(paramValue);
}
} else {
// 处理字符串类型
if (!obj[paramName]) {
// 如果如果paramName不存在,则创建对象的属性
obj[paramName] = paramValue;
} else if (obj[paramName] && typeof obj[paramName] === 'string') {
// 如果属性存在,并且是个字符串,那么就转换为数组
obj[paramName] = [obj[paramName]];
obj[paramName].push(paramValue);
} else {
// 如果是其它的类型,还是往数组里丢
obj[paramName].push(paramValue);
}
}
Если ваш параметр URL содержит специальные символы, например пробелы. Напримерurl="NaoNao.com/?name=Nao%20Nao", после получения значения объекта его необходимо декодировать, чтобы получить правильное значение
var original = getAllUrlParams().name; // 'Nao%20Nao'
var decode = decodeURIComponent(original); // 'Nao Nao'
Конкретная реализация и использование
Ниже приведена конкретная и полная реализация JS, вы можете скопировать ее обратно и использовать.
function getAllUrlParams(url) {
// 用JS拿到URL,如果函数接收了URL,那就用函数的参数。如果没传参,就使用当前页面的URL
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
// 用来存储我们所有的参数
var obj = {};
// 如果没有传参,返回一个空对象
if (!queryString) {
return obj;
}
// stuff after # is not part of query string, so get rid of it
queryString = queryString.split('#')[0];
// 将参数分成数组
var arr = queryString.split('&');
for (var i = 0; i < arr.length; i++) {
// 分离成key:value的形式
var a = arr[i].split('=');
// 将undefined标记为true
var paramName = a[0];
var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];
// 如果调用对象时要求大小写区分,可删除这两行代码
paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();
// 如果paramName以方括号结束, e.g. colors[] or colors[2]
if (paramName.match(/\[(\d+)?\]$/)) {
// 如果paramName不存在,则创建key
var key = paramName.replace(/\[(\d+)?\]/, '');
if (!obj[key]) obj[key] = [];
// 如果是索引数组 e.g. colors[2]
if (paramName.match(/\[\d+\]$/)) {
// 获取索引值并在对应的位置添加值
var index = /\[(\d+)\]/.exec(paramName)[1];
obj[key][index] = paramValue;
} else {
// 如果是其它的类型,也放到数组中
obj[key].push(paramValue);
}
} else {
// 处理字符串类型
if (!obj[paramName]) {
// 如果如果paramName不存在,则创建对象的属性
obj[paramName] = paramValue;
} else if (obj[paramName] && typeof obj[paramName] === 'string') {
// 如果属性存在,并且是个字符串,那么就转换为数组
obj[paramName] = [obj[paramName]];
obj[paramName].push(paramValue);
} else {
// 如果是其它的类型,还是往数组里丢
obj[paramName].push(paramValue);
}
}
}
return obj;
}
Как использовать эту функцию?
Можно вызывать параметр URL напрямую как объект~
Возьмите URL в начале статьи в качестве примера.
// http://NaoNao.com/?product=shirt&color=blue&newuser&size=m#Hello
getAllUrlParams().product; // 'shirt'
getAllUrlParams().color; // 'blue'
getAllUrlParams().newuser; // true
getAllUrlParams().NB; // undefined
getAllUrlParams('http://NaoNao.com/?NaoNao=shuai').NaoNao; // shuai
IE-несовместимое решение
Если не считать фееричной сучки вроде IE и каких-то очень старых браузеров, просто используйте в браузереURLSearchParamsинтерфейс. . . Этот интерфейс может напрямую принимать параметры в URL
// URL is http://NaoNao.com/?product=shirt&color=blue&newuser&size=m
const urlParams = new URLSearchParams(window.location.search);
// 判断参数是否存在
console.log(urlParams.has('product')); // true
// 获取参数对应的值
console.log(urlParams.get('product')); // "shirt"
Этот интерфейс также предоставляет более зрелые методы, такие какkeys(),Values(),а такжеentries(), как пользоваться этим интерфейсом, просто зайдите в официальную документацию напрямую, все равно очень напрасно пользоваться