Hướng dẫn javascript get url parameter

Getting a URL Parameter

Giả sử có ta có một URL như sau:

http://example.com/?product=shirt&color=blue&newuser&size=m

Function dưới đây giúp ta lấy được các URL paramater dưới dạng một object:

function getAllUrlParams(url) {
    // get query string from url (optional) or window
    var queryString = url ? url.split('?')[1] : window.location.search.slice(1);

    // we'll store the parameters here
    var obj = {};

    // if query string exists
    if (queryString) {

        // stuff after # is not part of query string, so get rid of it
        queryString = queryString.split('#')[0];

        // split our query string into its component parts
        var arr = queryString.split('&');

        for (var i = 0; i < arr.length; i++) {
            // separate the keys and the values
            var a = arr[i].split('=');

            // set parameter name and value (use 'true' if empty)
            var paramName = a[0];
            var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];

            // (optional) keep case consistent
            paramName = paramName.toLowerCase();
            if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();

            // if the paramName ends with square brackets, e.g. colors[] or colors[2]
            if (paramName.match(/\[(\d+)?\]$/)) {

                // create key if it doesn't exist
                var key = paramName.replace(/\[(\d+)?\]/, '');
                if (!obj[key]) obj[key] = [];

                // if it's an indexed array e.g. colors[2]
                if (paramName.match(/\[\d+\]$/)) {
                    // get the index value and add the entry at the appropriate position
                    var index = /\[(\d+)\]/.exec(paramName)[1];
                    obj[key][index] = paramValue;
                } else {
                    // otherwise add the value to the end of the array
                    obj[key].push(paramValue);
                }
            } else {
                // we're dealing with a string
                if (!obj[paramName]) {
                    // if it doesn't exist, create property
                    obj[paramName] = paramValue;
                } else if (obj[paramName] && typeof obj[paramName] === 'string'){
                    // if property does exist and it's a string, convert it to an array
                    obj[paramName] = [obj[paramName]];
                    obj[paramName].push(paramValue);
                } else {
                    // otherwise add the property
                    obj[paramName].push(paramValue);
                }
            }
        }
    }

    return obj;
}

Dưới đây là một số ví dụ khi sử dụng function này:

getAllUrlParams().product; // 'shirt'
getAllUrlParams().color; // 'blue'
getAllUrlParams().newuser; // true
getAllUrlParams().nonexistent; // undefined
getAllUrlParams('http://test.com/?a=abc').a; // 'abc'

Hoặc bạn có thể test trực tiếp tại:

https://codepen.io/ngohieuk57uet/full/yGmevr

Những điều cần biết trước khi sử dụng function này

  • Function này của chúng ta giả định các parameter được phân tách bằng ký tự &, như được chỉ ra trong W3C specifications. Tuy nhiên, định dạng parameter URL nói chung không được xác định rõ ràng, do đó, đôi khi ta có thể thấy ; hoặc & amp; làm separators.
  • Function của chúng ta vẫn hoạt động nếu một parameter không có dấu bằng hoặc nếu nó có dấu bằng nhưng không có giá trị.
  • Các giá trị của các parameters trùng được đặt vào trong một mảng.

Nếu bạn chỉ muốn một function để đưa vào code của mình để giải quyết vấn đề thì bạn đã hoàn thành. Nhưng nếu bạn muốn hiểu cách thức hoạt động của function, thì cùng xem tiếp.

Phần sau đây giả sử rằng bạn đã có một số kiến thức về JavaScript, bao gồm các functions, objects và arrays. Nếu không bạn hãy xem MDN JavaScript reference.

How the Function Works

Nhìn chung, function lấy một chuỗi truy vấn URL (phần sau dấu ? Và trước dấu # ) và trả ra dữ liệu trong một object.

Với dòng đầu tiên, nếu chúng ta đã chỉ định một URL, lấy mọi thứ sau dấu ?, nhưng nếu không, chỉ cần sử dụng URL của window:

var queryString = url ? url.split('?')[1] : window.location.search.slice(1);

Tiếp theo, chúng ta sẽ tạo một object để lưu trữ các parameter:

var obj = {};

Nếu chuỗi query tồn tại, chúng ta sẽ bắt đầu phân tích nó. Trước tiên, chúng ta phải đảm bảo tắt phần bắt đầu từ # vì nó không phải là một phần của chuỗi truy vấn:

queryString = queryString.split('#')[0];

Bây giờ chúng ta có thể chia chuỗi truy vấn thành các phần thành phần của nó:

var arr = queryString.split('&');

Điều đó sẽ cho chúng ta một mảng trông như thế này:

['product=shirt', 'color=blue', 'newuser', 'size=m']

Tiếp theo, chúng tôi sẽ lặp lại qua mảng này và chia từng mục thành một khóa và một giá trị, mà chúng tôi sẽ sớm đưa vào đối tượng của mình:

var a = arr[i].split('=');

Hãy để Lign gán khóa và giá trị cho các biến riêng lẻ. Nếu có một giá trị tham số, chúng tôi sẽ đặt nó thành true để chỉ ra rằng tên tham số tồn tại. Hãy thay đổi tùy thuộc vào trường hợp sử dụng của bạn:

var paramName = a[0];
var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];

Bạn có thể set tất cả các tên paramater và value thành chữ thường. Bằng cách đó, bạn có thể tránh các tình huống khi ai đó gửi dữ liệu đến một URL với dạng example = TRUE thay vì example = true và khiến script của bạn bị lỗi. Tuy nhiên, nếu query string của bạn cần phân biệt chữ hoa chữ thường, thì bạn nên bỏ qua phần này:

paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();

Tiếp theo, chúng ta cần xử lý các loại đầu vào khác nhau mà chúng ta có thể nhận được trong paramName. Đây có thể là một mảng được đánh index, một mảng không được đánh index hoặc một string thông thường.

Nếu nó là một mảng có đánh index, chúng ta muốn paramValue tương ứng là một mảng, với giá trị được chèn vào đúng vị trí. Nếu nó là một mảng không được đánh index, chúng ta muốn paramValue tương ứng là một mảng với phần tử được đẩy vào nó. Nếu nó là một string, chúng ta muốn tạo một property thông thường trong object và gán paramValue cho nó, trừ khi property đã tồn tại, thì trong trường hợp đó chúng ta muốn chuyển paramValue hiện có thành một mảng và push paramValue vào đó.

Để minh họa điều này, thì dưới đây là các ví dụ với output mà chúng ta mong đợi:

getAllUrlParams('http://example.com/?colors[0]=red&colors[2]=green&colors[6]=blue');
// { "colors": [ "red", null, "green", null, null, null, "blue" ] }

getAllUrlParams('http://example.com/?colors[]=red&colors[]=green&colors[]=blue');
// { "colors": [ "red", "green", "blue" ] }

getAllUrlParams('http://example.com/?colors=red&colors=green&colors=blue');
// { "colors": [ "red", "green", "blue" ] }

getAllUrlParams('http://example.com/?product=shirt&color=blue&newuser&size=m');
// { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }

Code để thực hiện chức năng:

if (paramName.match(/\[(\d+)?\]$/)) {
  var key = paramName.replace(/\[(\d+)?\]/, '');
  if (!obj[key]) obj[key] = [];

  if (paramName.match(/\[\d+\]$/)) {
    var index = /\[(\d+)\]/.exec(paramName)[1];
    obj[key][index] = paramValue;
  } else {
    obj[key].push(paramValue);
  }
} else {
  if (!obj[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);
  }
}

Cuối cùng, chúng ta trả về object với các paramater và value.

Nếu URL của bạn có bất kỳ ký tự đặc biệt được mã hóa nào như dấu cách (được encode thành %20), bạn cũng có thể decode chúng để nhận giá trị ban đầu như thế này:

// assume a url parameter of test=a%20space

var original = getAllUrlParams().test; // 'a%20space'
var decoded = decodeURIComponent(original); // 'a space'

Chỉ cần cẩn thận để không decode một cái mà đã decode nếu không bạn có thể mắc lỗi, đặc biệt là có liên quan đến phần trăm.

An Alternative for Modern Browsers

Nếu bạn không cần hỗ trợ các trình duyệt cũ, bạn có thể xem URLSearchParams interface, định nghĩa các method để làm việc với query string của URL:

// URL is http://example.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"

Nó cũng cung cấp các Object method quen thuộc như key (), value ()entry ().

Conclusion

Code trong bài viết này hoạt động cho các trường hợp sử dụng phổ biến nhất, và kết quả là bạn sẽ nhận được một object chứa các paramater truy vấn trong URL. Nếu bạn làm việc với bất kỳ trường hợp nào khác, chẳng hạn như dấu cách không phổ biến hoặc format đặc biệt, thì hãy kiểm tra lại và điều chỉnh cho phù hợp.

Nếu bạn muốn làm việc nhiều hơn với các URL, có sẵn các thư viện cụ thể, chẳng hạn như plugin URL jQuery và Medialize URI.js. Vì về cơ bản nó là thao tác với chuỗi, nên thường sử dụng các phương thức JavaScript đơn giản. Cho dù bạn sử dụng code riêng của mình hoặc sử dụng thư viện, thì hãy kiểm tra chắc chắn và đảm bảo rằng mọi thứ hoạt động cho các trường hợp sử dụng của bạn.

References

https://www.sitepoint.com/get-url-parameters-with-javascript/