Scripting

1. What's it?

Proxyman offers a scripting feature that the developer could write the JS code to manipulate the Request/Response in a flexible way.

2. Benefits

    Implement Map Local / Map Remote / Breakpoint by JS Code. 100x Faster
    Change the Request Content, includes Domain, Host, Scheme, Port, Path, HTTP Method, HTTP Headers, Query, Body (Encoded-Form, JSON, plain-text)
    Change the Response Content, includes HTTP Status Code, HTTP Headers, Body (JSON, Encoded-Form, plain-text, binary...)
    Provide plenty of built-in addons and libraries for common tasks, such as Hashing, Encode/Decode, JSON-Text transformer, Beautify,...
    Able to write your own JS Addons or Libraries
    Designed to replace Rewrite GUI Tool from Charles Proxy
    Assign and receive shared States between each script or current session with ShareState or Environment Variables

3. How to use it?

You can access the Scripting Tool by:
    Script Menu -> Script List (⌥⌘I)
    Open Menu Context from Right Click on the Flow -> Tools -> Scripting
Please Check out Snippet Code to see a collection of snippet JS codes for the Scripting Tool.

4. Scripting with GraphQL Requests

From Proxyman 2.27.0+, the Scripting Tool can work with GraphQL Request by a specific QueryName. Please check out the following GraphQL Document.

5. Examples

The following guide will show you how to write JS code to change the Request domain from Production to Localhost and change the Response Body
    1.
    Make sure you enable SSL for this domain before creating the script)
    2.
    Open Scripting Tool and create a new Script Entry (⌘N). You can right-click on the Request -> Tools -> Scripting => Proxyman will create a Script too
    3.
    Give the name and define a Matching Rule.
    4.
    Ex: Name=Test on Localhost endpoint, URL=https://proxyman.io
    5.
    Enable Run Script on Request and Response checkbox
    6.
    Start writing JS code for onRequest function
onRequest(context, url, request) {}
1
// Import UUID addons
2
const { uuidv4 } = require("@addons/UUID.js");
3
4
/// This func is called if the Request Checkbox is Enabled
5
/// You can manipulate the Request Data here before the request hits on the server
6
/// e.g. Add/Update/Remove: host, scheme, port, path, headers, queries, comment, color and body (json, form, plain-text, base64 encoded string)
7
///
8
/// Use console.log(request) to see all available fields
9
/// Action Menu -> Import File to import a JSON file and use in the script. Or Import directly with request.bodyFilePath = "~/Desktop/myfile.json" (Applied for Response too)
10
/// Use global object `sharedState` to share data between Requests/Response from different scripts (e.g. sharedState.data = "My-Data")
11
///
12
function onRequest(context, url, request) {
13
// print log
14
console.log(request);
15
16
// Change Production domain -> Localhost
17
request.method = "GET";
18
request.scheme = "http";
19
request.host = "localhost";
20
request.port = 8000;
21
22
// Add new header
23
request.headers["X-New-Header"] = "Hello From Scripting feature";
24
request.headers["UUID"] = uuidv4(); // generate random UUIDv4
25
delete request.headers["Key-Need-Delete"];
26
27
// Update or Add a new Query
28
request.queries["name"] = "Proxyman";
29
30
// Update Body
31
var body = request.body;
32
body["name"] = "Proxyman";
33
request.body = body;
34
35
// Or Map the body with a local file (Proxyman 2.25.0+)
36
// request.bodyFilePath = "~/Desktop/mockdata.json";
37
38
// Done
39
return request;
40
}
Copied!

onRequest() Object Format

context, url and request objects are defined by:
1
// context (readonly)
2
{
3
"scriptName": "<String> Your Script Name",
4
"matchingRule": "<String> Your Matching Rule",
5
"matchingMethod": "<String> Method",
6
"isEnableOnRequest": "Bool",
7
"isEnableOnResponse": "Bool",
8
"filePath": "<String> Script path",
9
"flow": { // Availble from 2.16.0+
10
"serverPort": "443",
11
"serverIpAddress": "104.18.230.83",
12
"clientIpAddress": "192.168.0.102",
13
"remoteDeviceName": "iPhone XR",
14
"remoteDeviceIP": "192.168.0.102",
15
"id": "51",
16
"clientPath": null,
17
"clientPort": "51494",
18
"clientName": null
19
},
20
}
21
22
// url (readonly)
23
url: String // => Present the full URL
24
25
// request
26
{
27
"method": "<String> HTTP Method. Accept string method. Ex: GET, POST, ...",
28
"scheme": "<String> Accept http or https",
29
"host": "<String> Host of the request. Ex: api.proxyman.io, localhost, ...",
30
"path": "<String>: Path of the URL. Ex: /v1/data",
31
"port": "<Int> Accept int port number. Ex: 443, 8080, ..",
32
"queries": "<[String: Any]> A JS Object (Dictionary) contains key values of the query",
33
"headers": "<[String: Any]> A JS Object (Dictionary) contains key values of the header",
34
"body": "Depend on the Content-Type header. It might be a dictionary for JSON and form, Plain Text or Base64 Encoded String",
35
"bodyFilePath": "<String><Optional> Set a body with a local file. See example in Snippet Code Page"
36
"rawBody": "<Readonly>: A raw body String or Base64 encoded string if it's a binary",
37
"preserveHostHeader": "<Bool> Preserve the Host",
38
"isURLEncoding": "<Bool> Determine if Proxyman will perform URLEncoding when constructing the final URL. Default is True"
39
}
40
Copied!
You can change any value of the request obj except rawBody
If the body variable is invalid format due to incorrect Content-Type in the Header. Please consider using the rawBody and manually parse the string.
The type of request.body replies on the Content-Type Header.
Content-Type Header
request.body
application/json or JSON families
Javascript Object
application/x-www-form-urlencoded
Javascript Object
plain-text or text-based Content-Type, Ex: application/js, text/css, text/html, ...
String
The rest (application/zip, application/octet-stream)
Base64 Encoded String
Check out common JS code from Snipped Code Page
7. Start writing code on onResponse function
1
/// This func is called if the Response Checkbox is Enabled
2
/// You can manipulate the Response Data here before it goes to the client
3
/// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string)
4
///
5
/// Use console.log(response) to see all available fields
6
///
7
function onResponse(context, url, request, response) {
8
console.log(response);
9
10
// Update or Add a new header
11
response.headers["Content-Type"] = "application/json";
12
13
// Update status Code
14
response.statusCode = 500;
15
16
// Update Body
17
var body = response.body;
18
body["new-key"] = "Proxyman";
19
response.body = body;
20
21
// Or Map the body with a local file (Proxyman 2.25.0+)
22
// response.bodyFilePath = "~/Desktop/mockdata.json";
23
24
// Done
25
return response;
26
}
Copied!

onResponse() Objects Format

context, url, request, and response objects are defined by:
1
// context (readonly): Same with onRequest
2
3
// url (readonly): Same with onRequest
4
5
// request (readonly): Same with onRequest
6
7
// response
8
{
9
"statusCode": "<Int> Status Code. Ex: 200, 400, 404,...",
10
"httpVersion": "<String><Readonly> The HTTP Version",
11
"statusPhrase": "<String><Readonly> HTTP Status Phrase. Ex Not Found, OK, ...",
12
"headers": "<[String: Any]> A JS Object (Dictionary) contains key values of the header",
13
"body": "Depend on the Content-Type header. It might be a dictionary for JSON and form, PlainText or Base64 Encoded String",
14
"rawBody": "<Readonly>: A raw body String or Base64 encoded string if it's a binary",
15
"bodyFilePath": "<String><Optional> Set a body with a local file. See example in Snippet Code Page"
16
}
Copied!
You can change statusCode, headers and body from the response Obj
If the body variable is invalid format due to incorrect Content-Type in the Header. Please consider using rawBody and manually parse the string.
The type of response.body replies on the Content-Type Header
Content-Type Header
request.body
application/json or JSON families
Javascript Object
application/x-www-form-urlencoded
Javascript Object
plain-text or text-based Content-Type, Ex: application/js, text/css, text/html, ...
String
The rest (application/zip, application/octet-stream)
Base64 Encoded String
You must return request and response object in onRequest and onResponse function

6. Built-in Addons and Libraries

Proxyman provides plenty of addons and libraries that help you achieve common tasks: Hashing, Encode/Decode, ...

7. Debugging JS Error

On certain occasions, you might encounter Javascript errors due to syntax errors, invalid code, ... You can debug by looking at error messages on the console or using console.log().

8. Use Scripting as a Mock API

From Proxyman 2.32.0, we can use Scripting Tool as a Mock API. It means your request would never hit the server, and you have to define a Response Body. This behavior is the same with Map Local.
This feature is useful when the actual Restful API is not available yet. You can define and test it locally.
To enable the Mock API:
    1.
    Open the Scripting Tool -> Select the Script
    2.
    Enable Run as Mock API checkbox.
Enable Mock API
Then you can define a Response as usual:
1
function onResponse(context, url, request, response) {
2
3
// Init new body
4
var body = {};
5
body["new-key"] = "Proxyman";
6
response.body = body;
7
8
// Or map from a file
9
// response.bodyFilePath = "~/Desktop/myfile.json"
10
11
// Done
12
return response;
13
}
Copied!

9. Notes

    You must return request and response Object in onRequest and onResponse function.
    Since Javascript doesn't have the Data object type, the Data Body will convert to Base64 Encoded String in Javascript.
    To pass Uint8Array, blob, or ArrayBuffer to the body, make sure you convert to Base64 Encoded String.
1
// Your binary, Uint8Array, blob data,...
2
var myData = fromFile();
3
4
// Import
5
const { btoa } = require('@addons/Base64.js');
6
7
// Convert to base64 encoded string
8
response.body = btoa(myData);
Copied!
Last modified 1mo ago