[GH-ISSUE #1012] Scripting changes order of Post Form Body #1008

Closed
opened 2026-03-03 19:23:43 +03:00 by kerem · 8 comments
Owner

Originally created by @Brontojoris on GitHub (Oct 5, 2021).
Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/1012

Originally assigned to: @NghiaTranUIT on GitHub.

Proxyman version?

2.33.0 (23300)

macOS Version?

10.15.7 (19H1419)

Steps to reproduce

  1. Enable a JS script containing:
function onRequest(context, url, request) {
  return request;
}
  1. Send a POST request with body as:
key1=apple&key2=banana&key3=orange&key4=pear&key5=grapes&key6=apricot
  1. Inspect the Request > Form view. The order of keys does not match what was sent.
  2. Disable the JS script.
  3. Resend the request
  4. Inspect the Request > Form view. The order of keys now matches what was sent.

Expected behaviour

The order of key/value pairs displayed in the Request > Form view should match the order that the key values were originally sent in.

Screenshots (optional)

Scripting On; Body Key/Value pairs out of order

body-out-of-order

Scripting Off; Body Key/Value pairs in order

body-in-order

Compose request

compose-request

Basic Request Script

script

Originally created by @Brontojoris on GitHub (Oct 5, 2021). Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/1012 Originally assigned to: @NghiaTranUIT on GitHub. ### Proxyman version? 2.33.0 (23300) ### macOS Version? 10.15.7 (19H1419) ### Steps to reproduce 1. Enable a JS script containing: ``` function onRequest(context, url, request) { return request; } ``` 2. Send a POST request with body as: ``` key1=apple&key2=banana&key3=orange&key4=pear&key5=grapes&key6=apricot ``` 3. Inspect the Request > Form view. The order of keys does not match what was sent. 4. Disable the JS script. 5. Resend the request 6. Inspect the Request > Form view. The order of keys now matches what was sent. ### Expected behaviour The order of key/value pairs displayed in the Request > Form view should match the order that the key values were originally sent in. ### Screenshots (optional) #### Scripting On; Body Key/Value pairs out of order ![body-out-of-order](https://user-images.githubusercontent.com/572375/135941359-2bc8854a-c2e9-4ed0-9598-56af44d9e9ef.png) #### Scripting Off; Body Key/Value pairs in order ![body-in-order](https://user-images.githubusercontent.com/572375/135941507-9160becf-029b-4d44-843e-5adfb1462283.png) #### Compose request ![compose-request](https://user-images.githubusercontent.com/572375/135941565-0858b9db-6b1d-4d30-a147-4bb436d23e20.png) #### Basic Request Script ![script](https://user-images.githubusercontent.com/572375/135941594-fca60d2e-2d8a-40f1-8383-2bcd4c793781.png)
kerem 2026-03-03 19:23:43 +03:00
Author
Owner

@NghiaTranUIT commented on GitHub (Oct 5, 2021):

Hey @Brontojoris, Thanks for your ticket.

Technically, when constructing the FormParam/Header from the Scripting (JSObject in JavascriptCore) to Dictionary (Swift), Dictionary (Swift) doesn't remain the key-order. As a result, the key-value order is to mess up as you describe.

I tried to solve it by using an Array (remain key-order), but it's difficult to manipulate (add/remove) the array than doing on the JSObject

Current approach (use Dictionary)

function onRequest(context, url, request) {
  request.body["key-1"] = "value 1"
  request.body["key-2"] = "value 2"
  return request;
}

If use Array

function onRequest(context, url, request) {
  request.body.append({key: "key-1", value: "value-1"})
  request.body.append({key: "key-2", value: "value-2"})
  return request;
}

For that reason, I choose to use JSObject but the trade-off is the key order.


Just wondering: Does the key-order of Encoded Param affect the response? 🤔

If yes, I might find alternative solution to fix it.

<!-- gh-comment-id:933983680 --> @NghiaTranUIT commented on GitHub (Oct 5, 2021): Hey @Brontojoris, Thanks for your ticket. Technically, when constructing the FormParam/Header from the Scripting (JSObject in JavascriptCore) to Dictionary (Swift), Dictionary (Swift) doesn't remain the key-order. As a result, the key-value order is to mess up as you describe. I tried to solve it by using an Array (remain key-order), but it's difficult to manipulate (add/remove) the array than doing on the JSObject ## Current approach (use Dictionary) ```js function onRequest(context, url, request) { request.body["key-1"] = "value 1" request.body["key-2"] = "value 2" return request; } ``` ## If use Array ```js function onRequest(context, url, request) { request.body.append({key: "key-1", value: "value-1"}) request.body.append({key: "key-2", value: "value-2"}) return request; } ``` For that reason, I choose to use JSObject but the trade-off is the key order. ------------------- Just wondering: Does the key-order of Encoded Param affect the response? 🤔 If yes, I might find alternative solution to fix it.
Author
Owner

@Brontojoris commented on GitHub (Oct 5, 2021):

Hi @NghiaTranUIT ,

Thanks for the quick reply. My use case is debugging Adobe Analytics beacons from iOS/Android mobile apps. Adobe send the data in a quirky format which means I am using the Request Form view a lot, and the order of the key/values is quite important. Loosely translated to JSON, their format looks a bit like:

{c:{
  a:{key1:'value 1',
     key2:'value 2'
  },
  appName:{
      dim:{
        key3:'value 3',
        key4:'value 4'
  },
  key5:'value 5',
  key6:'value 6',
  etc:'etc'
 }
}

Except in the raw body, it looks more like:

&c.&a.&key1=value%201&key2=value%202&.a&appName.&dim.&key3=value%203&key4=value%204&.dim&.appName&key5=value%205&key6=value%206&etc=etc&.c <- The dots before and after the keys represent the nesting of the structure.

As a result, preserving the ordering of keys is quite important to me.

I'm using the Scripting tool to grab some of these values so I can display them in custom columns of the request list.

I would be happy for a solution where I can using the Scripting tool to clone a copy of the request object, and then manipulate that, in the hope that it doesn't mess up the key order, and I tried different things like Object.freeze, and JSON.parse(JSON.stringify(request). But right now, it seems that even having Scripting on, will mess it up.

I would even consider making a custom preview panel, but am waiting for Plugins functionality to be released.

<!-- gh-comment-id:934020819 --> @Brontojoris commented on GitHub (Oct 5, 2021): Hi @NghiaTranUIT , Thanks for the quick reply. My use case is debugging Adobe Analytics beacons from iOS/Android mobile apps. Adobe send the data in a quirky format which means I am using the Request Form view _a lot_, and the order of the key/values is quite important. Loosely translated to JSON, their format looks a bit like: ``` {c:{ a:{key1:'value 1', key2:'value 2' }, appName:{ dim:{ key3:'value 3', key4:'value 4' }, key5:'value 5', key6:'value 6', etc:'etc' } } ``` Except in the raw body, it looks more like: `&c.&a.&key1=value%201&key2=value%202&.a&appName.&dim.&key3=value%203&key4=value%204&.dim&.appName&key5=value%205&key6=value%206&etc=etc&.c` <- The dots before and after the keys represent the nesting of the structure. As a result, preserving the ordering of keys is quite important to me. I'm using the Scripting tool to grab some of these values so I can display them in custom columns of the request list. I would be happy for a solution where I can using the Scripting tool to clone a copy of the request object, and then manipulate that, in the hope that it doesn't mess up the key order, and I tried different things like `Object.freeze`, and `JSON.parse(JSON.stringify(request)`. But right now, it seems that even having Scripting on, will mess it up. I would even consider making a custom preview panel, but am waiting for Plugins functionality to be released.
Author
Owner

@NghiaTranUIT commented on GitHub (Oct 5, 2021):

Thanks for your insight @Brontojoris 👍

The reason why JSON.parse(JSON.stringify(request) orObject.freeze doesn't work is because Proxyman will parse JSObject to Dictionary (swift) after you calling return request;.

I have an idea to fix it. Let me try and send you a beta build soon 👍

<!-- gh-comment-id:934035176 --> @NghiaTranUIT commented on GitHub (Oct 5, 2021): Thanks for your insight @Brontojoris 👍 The reason why `JSON.parse(JSON.stringify(request)` or`Object.freeze` doesn't work is because Proxyman will parse JSObject to Dictionary (swift) after you calling `return request;`. I have an idea to fix it. Let me try and send you a beta build soon 👍
Author
Owner

@NghiaTranUIT commented on GitHub (Oct 6, 2021):

Hey @Brontojoris, if you don't mind, please try this beta build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.33.0_Try_to_fix_param_order.dmg

I did a little trick when passing Swift Object to JavascriptCore, which keep the order of Headers, Query and Form Body 👍

Please let me know if it works.

<!-- gh-comment-id:935198977 --> @NghiaTranUIT commented on GitHub (Oct 6, 2021): Hey @Brontojoris, if you don't mind, please try this beta build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.33.0_Try_to_fix_param_order.dmg I did a little trick when passing Swift Object to JavascriptCore, which keep the order of Headers, Query and Form Body 👍 Please let me know if it works.
Author
Owner

@Brontojoris commented on GitHub (Oct 6, 2021):

Hi @NghiaTranUIT ,

I tested the beta, and it's working great on both my test case, and also on the Adobe requests.

Thank you so much for the speedy turnaround! :)

image

<!-- gh-comment-id:935238561 --> @Brontojoris commented on GitHub (Oct 6, 2021): Hi @NghiaTranUIT , I tested the beta, and it's working great on both my test case, and also on the Adobe requests. Thank you so much for the speedy turnaround! :) ![image](https://user-images.githubusercontent.com/572375/136127940-10d40189-b2ef-465d-9b8f-6d88ff8ecefa.png)
Author
Owner

@NghiaTranUIT commented on GitHub (Oct 6, 2021):

awesome 👍 I will test it carefully then shipping it in the next release 😄

<!-- gh-comment-id:935240398 --> @NghiaTranUIT commented on GitHub (Oct 6, 2021): awesome 👍 I will test it carefully then shipping it in the next release 😄
Author
Owner

@NghiaTranUIT commented on GitHub (Oct 6, 2021):

I have an updated build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.33.0_Keep_Key-Order_v2.dmg

It fixes some issues if your request has multiple Header/Query/FormParam, which have the same key 👍

Thank you in advance 🙌

<!-- gh-comment-id:935683086 --> @NghiaTranUIT commented on GitHub (Oct 6, 2021): I have an updated build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.33.0_Keep_Key-Order_v2.dmg It fixes some issues if your request has multiple Header/Query/FormParam, which have the same key 👍 Thank you in advance 🙌
Author
Owner

@Brontojoris commented on GitHub (Oct 13, 2021):

Apologies for the delayed reply. I tested version 2.33.0_Keep_Key-Order_v2 of the app, and can confirm everything is still working well for my use case.

<!-- gh-comment-id:941969115 --> @Brontojoris commented on GitHub (Oct 13, 2021): Apologies for the delayed reply. I tested version 2.33.0_Keep_Key-Order_v2 of the app, and can confirm everything is still working well for my use case.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Proxyman#1008
No description provided.