Extracting multiple values from response header

I have a problem with extracting multiple values (and storing them into separate variables) from response header.

In my test case, after first request I get response with some important data in the response header “location”, which I need to use in second request. To automate test case, I’m trying to chop that long URL into smaller chunks/variables that I will pass in second request as a parameters.

My question: How to do this?

I’ve managed to store whole “location” header into variable and reuse it in my next request but that is not good in every case I need to cover. I’ve also tried using split but I can get only 1 variable value this way.

Your going to have to declare each of the variables, so why can’t you just split the original response four times.

Creating a function to “parse” the location would be a lot of code.
If you can target each key\value using split, then I’d just do it this way.

Thank you @michaelderekjones for suggestion, it didn’t come to me that I can perform 4 x splits on the same variable instead of 1. :saluting_face:

So I tried something like this:

let upload_URL = pm.response.headers.get('location');
pm.environment.set("key", upload_URL.split('=')[1]);
pm.environment.set("name", upload_URL.split('=')[2]);
pm.environment.set("expires", upload_URL.split('=')[3]);
pm.environment.set("signature", upload_URL.split('=')[4]);

and only last variable is correct. The rest are incorrect because on the left side of the desired value separator is “=” and on the right it is “&”. So I need extract value between “=” and “&”. I don’t how to do this with split. Should I use RegEx or there is another way?

Can you post an example (as text) and I’ll have a go. (Might not be today though).

It will be via Regex, split or a combination.

This function seems to work.

// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

// let upload_URL = pm.response.headers.get('location');
let url = "https://postman-echo.com/get?key=key-123&name=name-123&expires=expires-123&signature=signature-123";

function getParameterByName(name, url = window.location.href) {
    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, ' '));
}

console.log(getParameterByName("key", url));
console.log(getParameterByName("name", url));
console.log(getParameterByName("expires", url));
console.log(getParameterByName("name", url));

Full text:

https://qa2.testingstore.com/api/v2.0/upload/process?key=local-804ef6daf465482188c3a5951963cc36&name=QA2_2022-12-22_15-19_Testing-API_V2.png&expires=2022-12-22T14%3a29%3a46.7116531%2b00%3a00&signature=1aE9hgpcCsM

The function I posed seems to be able to handle your url string.

// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

// let upload_URL = pm.response.headers.get('location');
let url = "https://qa2.testingstore.com/api/v2.0/upload/process?key=local-804ef6daf465482188c3a5951963cc36&name=QA2_2022-12-22_15-19_Testing-API_V2.png&expires=2022-12-22T14%3a29%3a46.7116531%2b00%3a00&signature=1aE9hgpcCsM";

function getParameterByName(name, url = window.location.href) {
    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, ' '));
}

console.log(getParameterByName("key", url)); // local-804ef6daf465482188c3a5951963cc36
console.log(getParameterByName("name", url)); // QA2_2022-12-22_15-19_Testing-API_V2.png
console.log(getParameterByName("expires", url)); // 2022-12-22T14%3a29%3a46.7116531%2b00%3a00
console.log(getParameterByName("signature", url)); // 1aE9hgpcCsM

That is awesome but to be honest I need some time to understand what is going on here. :exploding_head: :grinning: I started to explore other JS methods like substr() and substring() but this… :face_holding_back_tears: Thank you very much! :saluting_face:

Postman uses JavaScript a lot so its worth while getting your head around the basics.

JSON, JavaScript objects, and arrays for a starter. Regex is also something worth learning.

When you get something complicated, I always look to Google first.

No point in trying to re-create something that has been done hundreds of time before. This includes Regex examples.

The post on Stackoverflow that this function comes from has been upvoted 10019 times, so I’m fairly certain it would be a better example that something I could come up with. :slight_smile:

Hello,

@michaelderekjones Could I have additional question with that topic to you (or anyone that can help)? Recently I noticed that I something’s wrong with my solution.

My “location” header in response have value as below:

let url = "https://qa2.testingstore.com/api/v2.0/upload/process?key=local-d8ae17e1be6348a4a2d06302e3e76131&name=QA2_2023-01-18_13-49_Testing-API_V2.png&expires=2023-01-18T13%3a19%3a14.6912931%2b00%3a00&signature=IR-q7MKOzZk";

so this function above should:

pm.environment.set("expires", (getParameterByName("expires", url))); //2023-01-18T13%3a19%3a14.6912931%2b00%3a00

but instead I am getting this:

pm.environment.set("expires", (getParameterByName("expires", url))); //2023-01-18T13:19:14.6912931+00:00

My question is: Why “%3a” is changed to “:” during setting a variable?

@meatinaplasticsack

%3A is the escaped version of :

: is a reserved character so can’t be used in a URL.

HTTP - URL Encoding (tutorialspoint.com)

Yes, I know that “%3a” is encoded “:” but I did not understand why it was switched.

After some additional verification I know that WHY the value was changed during setting variable. It’s because decodeURIComponent() in the function. As a matter of fact it seems that I don’t need decoding anyway and in the end I removed it entirely. Conclusion: always use code tat you fully understand. :smiley:

Additional information

Some interesting implication of this “decoding/encoding”. Before I decided to remove decoding I tried to encode this value again before reusing it in next request. I used this code:

console.log(`Decoded "expires" variable is: ${pm.environment.get('expires')}`);
let encoded = encodeURIComponent(pm.environment.get("expires"));
pm.environment.set("expires", encoded);
console.log(`Encoded "expires" variable is: ${pm.environment.get('expires')}`);

Value without decoding/encoding (this works fine):
2023-01-18T16%3a14%3a14.6521723%2b00%3a00

Value after decoding and encoding it again (this is not working):
2023-01-18T16%3A14%3A14.6521723%2B00%3A00

After encoding it again and putting as a parameter to next request URL, I get 403 forbidden. I manually removed whole decoding/encoding thing from even happening, it works like it should. Why? :thinking: Request URL is not case sensitive, right? :face_with_raised_eyebrow:

Sorry, not sure why its doing this.

Both of those values seem to return the same value when decoded which should be the deciding factor when the request is sent.

I’ve looked at the collectionVariable and the string looks ok here.

console.log(decodeURIComponent("2023-01-18T16%3a14%3a14.6521723%2b00%3a00"));
console.log(decodeURIComponent("2023-01-18T16%3A14%3A14.6521723%2B00%3A00"));

image

Are Domains & URLs Case Sensitive? (9 Important Facts) (techpenny.com)

Well, maybe at some point will be able to explain that weird behavior. Anyway, thank you @michaelderekjones for all your help! You really saved me with that function. :wink: