Passing multiple URL parameters to Classic ASP

2019-07-31 05:23发布

问题:

Edit: Turns out my JavaScript function is not working as I thought, but please help with the ASP issue whilst I fix the JavaScript.

Edit 2: Using alert(JSON.stringify(sales)) to see the object I get this:

{"712":{"KR":1,"LR":0},"713":{"KR":1,"LR":0}}

Edit 3:

Need to re-write my sales script, i'm trying to use objects but it doesn't seem to be working as I don't have much experience with this part of JS.

var products = { 
    "KR" : 4,
    "LR" : 6 
};
var sale = [ ];

function sale(id,product,value) 
{
    this.id = function prod(product,value) 
    {
        this.product = product;
        this.value = value;
    }
}

sale("N51","KR",0);

Hopefully you can see what i'm trying to do, but it is probably very wrong.

And thanks for that long post, it is very helpful, I will work on all of that as soon as the above code works


Okay, I have this JavaScript script that will sort out the sales for individual images.

712 and 713 is the image ID. Then KR and LR are the products, it only adds them to the URL variable if there is actually a sale for them.

function submitSales() 
{
    //URL Variable
    var urlVariable = "?sales=";

    for (x in sales)
    {
        urlVariable = urlVariable + x + "-";
        for (s in sales[x])
        {
            if (sales[x][s] > 0)
            {
                urlVariable = urlVariable + s + ":" + sales[x][s] + ",";
            }
        }
    }
    urlVariable = urlVariable.substring(0, urlVariable.length - 1);
}

If I add sales for 3 products I get left with the following string: ?sales=712-KR:1,LR:1,713-KR:1

Now what would the best way of first of all separating the two images sales, so I will be left with:

712-KR:1,LR:1 713-KR:1

Then really I need to have them in a array that would look something like:

image(0) = 712 = product(0) = KR = 1
                 product(1) = LR = 1
image(1) = 713 = product(0) = KR = 1

I don't really know how ASP array's work that well, from what I read they actually suck.

回答1:

I don't really know how ASP array's work that well, from what I read they actually suck.

They do, but in this case it does not matter.

General Stuff

First off, your JavaScript is wrong.

  • x and s are never declared, thus they are global. Don't do this, always declare all variables with var.
  • You are not properly encoding your URL parameters. This is bound to blow up, always use proper encoding (encodeURIComponent() in this case).
  • Avoid relying on global variables. Pass in the sales variable as an argument.
  • Avoid a naked for .. in to iterate an object. Use hasOwnProperty() as a security precaution. This is good practice to defend against the case where the Object prototype has been extended. Alternatively, use one of the many JS librarys that give you a universal each() function. Underscore.js, Sugar.js, jQuery, all provide such a function. Or write one yourself, like I did below.

Secondly, ASP already solves this problem very nicely.

If you pass multiple parameters with the same name in your query string, the server puts them in a collection for you. (In fact, the Request object always contains collections, even if you pass in an URL-parameter only once.)

So when you query

http://foo/bar?sale=712-KR%3A1&sale=712-LR%3A1&sale=713-KR%3A1

Note the encoded :

then the ASP engine will deliver three distinct values, in one collection, like this:

"712-KR:1", "712-LR:1", "713-KR:1"
  • This collection is 1-based, so that Request("sale")(1) will be "712-KR:1" and so on.
  • You can use Request("sale").Count to find out how many parameters with any given name there are.

At this point I suggest two things.

  • Rewrite your client code so that it sends multiple parameters with the same name.
  • Switch to dictionaries on the ASP side instead of trying to use arrays.

Client

js Helper (this might actually be unnecessary if you are using a library already)

function each(obj, callback) {
    var key;

    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            callback(key, obj[key]);
        }
    }
}

js

function submitSales(sales) {
    var urlVariable, params = [];

    each(sales, function (saleId, sale) {
       each(sale, function (itemId, val) {
           var param = saleId + "-" + itemId + ":" + val;

           if (val > 0) {
               params.push( encodeURIComponent(param) );
           }
       });
    });

    urlVariable = "?sale=" + params.join("&sale=");

    // ...
}

Server

ASP helpers

Function NewDict() 
    Set NewDict = Server.CreateObject("Scripting.Dictionary")
End Function

Function Count(ary)
    If IsArray(ary) Then
        Count = UBound(ary) - LBound(ary) + 1
    Else
        Count = vbEmpty
    End If
End Function

ASP

Function ParseSales(params) 
    Dim sales, sale, parts, saleId, value, product

    Set sales = NewDict()

    For Each sale In params
        parts = Split(sale, "-")
        saleId = parts(0)

        ' let's be careful and do a sanity check 
        If Count(parts) = 2 and IsNumeric(saleId) Then
            product = Split(parts(1), ":")

            If Count(product) = 2 Then
                If Not sales.Exists(saleId) Then
                    sales.Add saleId, NewDict()
                End If

                sales(saleId).Add product(0), product(1)
            Else
                ' Invalid parameter format, react accordingly
            End If
        Else
            ' Invalid parameter format, react accordingly
        End If
    Next

    Set ParseSales = sales
End Function

Now you can do all kinds of things on the server side

Dim sales, saleId
Set sales = ParseSales(Request("sales"))

Response.Write sales.Exists("712")        ' -> True
Response.Write sales.Exists("714")        ' -> False
Response.Write sales("712").Count         ' -> 2
Response.Write sales("712")("KR")         ' -> 1
Response.Write sales("712").Exists("XR")  ' -> False

Response.Write Join(sales.Keys(), "; ")         ' -> 712; 713
Response.Write Join(sales("712").Keys(), "; ")  ' -> KR; LR

For Each saleId In sales
    ' saleId will be "712" and so on, use sales(saleId) to get the 
    ' actual object and do something with it
Next