1

I have a proxy that requests for services get routed through. This is working great for my map services, however I have geoprocessing services as well that must be accessed using the proxy. These geoprocessing services require a file upload and some other parameters get passed along with the file. Since the parameters get appended to the end of the URL with every POST request, the URL is never the same. I don't know how to set the serverUrl setting in proxy.config to allow for this.

The documentation lists a property called "matchAll" where if it is true, it should forward anything with the path in the serverUrl, if my understanding is correct:

matchAll="true": When true all requests that begin with the specified URL are forwarded. Otherwise, the URL requested must match exactly.

I have tried setting it to both true and false in my config file and neither seem to work. Additionally, the documentation for the "url" setting in the proxy config file seems to contradict the "matchAll" setting (which is why I tried it both ways)...

url: Location of the ArcGIS Server service (or other URL) to proxy. Specify either the specific URL or the root (in which case you should set matchAll="false").

This is my current proxy.config file:

<ProxyConfig allowedReferers="https://www.mydomain.com/*"
         mustMatch="true"
         logFile="proxyLog.txt"
         logLevel="Warning">
<serverUrls>
  <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatManagement/HabitatManagement/GPServer/"
             username="username"
             password="password"
             matchAll="true"/>
  <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatData/MapServer"
             username="username"
             password="password"
             matchAll="true" />
  <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatClassification/GPServer/uploads/upload"
             username="username"
             password="password"
             matchAll="true" />
</serverUrls>

I could make it very general and just have a `url="https://www.mydomain.com" but I really don't want to do that because only specific services need authentication on our server.

Ultimately, I end up with 403 errors in the console like this one:

{"error": {"code": 403,"message":"Proxy has not been set up for this URL. Make sure there is a serverUrl in the configuration file that matches: https://www.mydomain.com/myServer/rest/services/HabitatManagement/HabitatManagement/GPServer/HabitatManagement/submitJob?f=json&Input_Zip_File=%7B%22itemID%22%3A%22ib98735f1-f9d7-4858-a723-1e2dbec6acd7%22%7D&State_Abbreviation=PA&Email_Address=xxx%40xxx.xxx

Example of the GP services:

 classifyGP = new Geoprocessor("https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatClassification/GPServer/HabitatClassification");

        function classifyUpload() {
            //whole bunch of validation text here...
            else if (email == "") {
                $('#classify-validation-text').empty();
                $("#classify-emailValidation").text("Please enter an email address.");
                $('#classify').button('enable').removeClass('ui-state-disabled');
            }
            else {
                $('#classify-validation-text').empty();
                $('#classify-emailValidation').empty();
                //upload the zip file and get back the itemID (via uploadSucceeded)
                var upload = esri.request({
                    url: "https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatClassification/GPServer/uploads/upload",
                    form: dojo.byId("classifyUploadForm"),
                    content: { f: 'json' },
                    handleAs: 'json',
                }).then(classifyUploadSucceeded, classifyUploadFailed);
            }
        }

        function classifyUploadSucceeded(response) {
            var itemID = response["item"].itemID;
            var dataFile = new esri.tasks.DataFile();
            //This is the zip file (itemID)
            dataFile.itemID = itemID;
            var stateAbbrv = dom.byId("stateAbbrev").value;
            var emailAddr = dom.byId("emailAddress").value;
            console.log("File upload successful");
            var params = { "Input_Zip_File": dataFile, "State_Abbreviation": stateAbbrv, "Email_Address": emailAddr };
            console.log('Input parameters: ' + dojo.toJson(params));
            //Show spinner
            standby.show();
            classifyGP.submitJob(params, classify_gpJobComplete, classify_gpJobStatus, function (error) {
                console.error(error.jobStatus + '(' + error.jobId + '):' + dojo.toJson(error));
            });
        }

        function classify_gpJobComplete(result) {
            console.log(result.jobStatus + '(' + result.jobId + ')');
            //Get error messages to return to the user if there are any
            var errorMessages = [];
            var jsonResults = dojo.toJson(result);
            var jsonParsed = JSON.parse(jsonResults);
            for (var i = 0; i < jsonParsed.messages.length; i++) {
                var message = jsonParsed.messages[i];
                if (message.type == "esriJobMessageTypeError") {
                    //Do not add generic "Failed to execute" ESRI messages to the error message array
                    if (!message.description.match(/^Failed/)) {
                        errorMessages.push(message.description);
                    }
                };
            }

This is the proxy rule I have set at the beginning of my JS code:

urlUtils.addProxyRule({
            urlPrefix: "https://www.mydomain.com",
            proxyUrl: "/appName/proxy/proxy.ashx"
        });
  • How are you doing the file upload? Your error message seems to indicate you've got the file uploaded because you're passing the itemID to the input_zip_param. It's been awhile, but I think if you setup proxy with esri.request in JS, it's all just handled. Basic JS code sample here: community.esri.com/thread/72392 (but its been awhile, I could be wrong) – KHibma Oct 25 '18 at 15:01
  • Ya, the GPK here has a HTML file inside that has a proxy referenced. I dont have the proxy.config, but I'm sure it's similar to what you've posted arcgis.com/home/item.html?id=d31cc0d3bfbd4e7ba14dc4c6e5a8bb77 – KHibma Oct 25 '18 at 15:04
  • What if you add an * after GPServer? url="mydomain.com/myServer/rest/services/HabitatManagement/…*" – enolan Oct 25 '18 at 17:30
  • @enolan - sadly I have tried that and it does not work. – MKF Oct 25 '18 at 20:27
  • @KHibma - That does not seem to work for me for whatever reason. I have added a proxy rule (instead of using esri.config.defaults.io.proxyUrl) because the documentation states to do that instead when you're using a username and password for authentication in proxy.config. I have added my JS for one of my GP services and the proxy rule I have in place. Map services and file upload work correctly, but "submitJob" process does not. – MKF Oct 25 '18 at 20:45
0

Well...I finally got it working. I still don't know what I did to get it to work but on the 500th try it did. The only things I think I changed between the last try and this one was updating the path to the proxy log file in the proxy's web.config file. I also fixed my one GP service that still had a URL that ended in /uploads/upload to be more general and just ending in /GPServer like the other one (see original post). I hadn't changed it earlier because I haven't been testing submissions with that service, I was only testing the habitat management one. Maybe that's what fixed it? I also republished my app, obviously.

Here's the final code:

JS

urlUtils.addProxyRule({
            urlPrefix: "https://www.mydomain.com",
            proxyUrl: "/appName/proxy/proxy.ashx"
        });

proxy.config

<ProxyConfig allowedReferers="https://www.mydomain.com/*"
             mustMatch="true"
             logFile="proxyLog.txt"
             logLevel="Warning">
    <serverUrls>
      <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatManagement/HabitatManagement/GPServer"
                 username="username"
                 password="password"
                 matchAll="true"/>
      <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatData/MapServer"
                 username="username"
                 password="password"
                 matchAll="true" />
      <serverUrl url="https://www.mydomain.com/myServer/rest/services/HabitatMonitoring/HabitatClassification/GPServer/"
                 username="username"
                 password="password"
                 matchAll="true" />
    </serverUrls>
</ProxyConfig>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.