1

I am posting uploaded files to classic ASP using AJAX and I need to be able to repost the post stream to another site.

I can verify that the posted data from AJAX request is correct. I can read the files and save them on the local server. I can change the AJAX url to the "reposting" URL and it works fine.

The issue is simply reading the posted data and reposting.

let data = formData; //all the files we are uploading
$.ajax({
        url: `MyMultiFileHandler.asp`,
        cache: false,
        contentType: false,
        processData: false,
        enctype: 'multipart/form-data',
        data: data,
        type: `POST`,
    }).done(function(data) {
        console.log(`data: `, data);
    }).fail(function(xhr, textStatus, errorThrown) {
        console.log(xhr, textStatus, errorThrown);
    }).always(function() {
    });

MyMultiFileHandler.asp

dim postData: postData=request.Form

Set ServerXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
ServerXmlHttp.open "POST", "https://example.com", false

'ServerXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
ServerXmlHttp.setRequestHeader "Content-Type", "multipart/form-data"
ServerXmlHttp.setRequestHeader "Content-Length", Len(postData)

ServerXmlHttp.send postData

If ServerXmlHttp.status = 200 Then
    TextResponse = ServerXmlHttp.responseText
    response.write TextResponse ' Success! 0 files uploaded!
Else
    response.write err.description & "fault 6"
    response.end
End If

Set ServerXmlHttp = Nothing

EDITED to add the controller being called Here is the controller and function that's being called on the "repository" server:

    [HttpPost]
    //[ValidateAntiForgeryToken]
    public ActionResult Upload(string folderpath, IEnumerable<HttpPostedFileBase> imgfiles)
    {
        folderpath = !String.IsNullOrEmpty(folderpath) ? folderpath.Replace("|", "\\") : "";

        bool exists = System.IO.Directory.Exists(Server.MapPath($"/imagerepository/{folderpath}"));

        if(!exists)
            System.IO.Directory.CreateDirectory(Server.MapPath($"/imagerepository/{folderpath}"));
        int count = 0;
        var fileName = "";
        if (imgfiles != null)
        {
            foreach (var file in imgfiles)
            {
                if (file != null && file.ContentLength > 0)
                {
                    fileName = file.FileName;
                    var path = Path.Combine(Server.MapPath($"/imagerepository/{folderpath}"), fileName);
                    //return new JsonResult { Data = "Successfully " + count + " file(s) uploaded: " + fileName + " path " +path};
                    file.SaveAs(path);
                    count++;
                }
            }
        }
        return new JsonResult { Data = "Successfully upoaded " + count + " file(s)"};
    }
Chris
  • 650
  • 7
  • 20
  • 1
    What status code / error is returned? And shouldn't you be using `LenB` instead of `Len` for the content length? – Adam Feb 17 '21 at 18:16
  • I edited the question to add the code of the controller that's being called on the "repository" server. No error is being returned. And the directory is actually created if it doesn't exist. But...no files are processed. I get a "Successfully uploaded 0 files". – Chris Feb 17 '21 at 18:27
  • 1
    When the content type is multipart/form-data, you cannot access posted data using Request.Form.. Have you checked if `postData=request.Form` has any value? – Flakes Feb 18 '21 at 03:47
  • @Flakes is right if you pass `multipart/form-data` to Classic ASP you can only parse it manually using `Response.BinaryRead(Request.TotalBytes)`. Can’t see how this ever worked as `Request.Form` will be empty. – user692942 Feb 18 '21 at 08:32
  • Does this answer your question? [How to upload files with asp-classic](https://stackoverflow.com/questions/12190305/how-to-upload-files-with-asp-classic) – user692942 Feb 18 '21 at 08:35
  • user692942 -- no. I have no problem uploading files. What I'm trying to do is redirect the post stream to another website. – Chris Feb 18 '21 at 14:35
  • 1
    @Flakes -- that is the issue. No, it has no value. That was the point. I can get the stream using binaryRead but I can't repost that stream. I don't mind manually parsing it at all if I could simply create another post transaction with multiple files. If there was some sort of ServerXML postData.append... – Chris Feb 18 '21 at 14:39
  • @Chris you still not explained how you uploaded before because like already stated you can’t access `Request.Form` when posting `multipart/form-data`? Were you just not using Classic ASP or perhaps you posted using `application/x-www-form-urlencoded` (but that wouldn’t support multiple files)? – user692942 Feb 19 '21 at 11:05
  • @user692942 -- I used a standard ajax call. What I'm trying to do is having to avoid posting the form data twice with ajax. I wanted to post it once to the local site and then post it to the two other sites that get the info without having to generate another ajax. Part of this is the client's requirement. There is a site that they don't want exposed in the DOM . – Chris Feb 19 '21 at 18:30
  • @Chris how does that even start to answer the questions I've asked? AJAX is just the mechanism for sending a request to the server, but was your server running Classic ASP or something else, did you use `multipart/form-data`? You suggested you already had this working in Classic ASP but I’m struggling to see how that was the case. Basically your explanation so far isn’t very clear. – user692942 Feb 19 '21 at 19:22
  • @Chris never tried this personally but ideally you just want to pass the request on so why not just use `postData = Request.BinaryRead(Request.TotalBytes)` to pull the raw binary then send that as the `ServerXmlHttp` request. – user692942 Feb 19 '21 at 19:30
  • 1
    @User692942...Already tried that. It's not possible. Basically, when the request is sent, it's sent as binary, converted to a stream and converted back to binary. Or at least that's what it looks like. And I didn't mean to suggest I had this running. What I meant was, I can verify all my requests simply by using jquery ajax and not posting from the back end which is classic ASP. IOW, there's nothing wrong with the the sites to which I'm posting. They work as expected. However, the client does not want to use ajax for one of the sites. So, I need to post to that site on the back side. – Chris Feb 19 '21 at 22:11
  • If it is copying the file to one location, then it should be able to copy to two locations by simply adding the extra code to do so. On my client's sites, one for retail and one for wholesale clients, he can upload from either website and the image is rescaled, compressed and then saved to the image folders on both websites. Only thing that can get in the way of that is folder/write permissions. – WilliamK Jun 29 '21 at 02:18

0 Answers0