Loading cross-domain endpoint with AJAX

前端 未结 9 1671
醉酒成梦
醉酒成梦 2020-11-21 05:20

I\'m trying to load a cross-domain HTML page using AJAX but unless the dataType is \"jsonp\" I can\'t get a response. However using jsonp the browser is expecting a script m

9条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-21 05:57

    I'm posting this in case someone faces the same problem I am facing right now. I've got a Zebra thermal printer, equipped with the ZebraNet print server, which offers a HTML-based user interface for editing multiple settings, seeing the printer's current status, etc. I need to get the status of the printer, which is displayed in one of those html pages, offered by the ZebraNet server and, for example, alert() a message to the user in the browser. This means that I have to get that html page in Javascript first. Although the printer is within the LAN of the user's PC, that Same Origin Policy is still staying firmly in my way. I tried JSONP, but the server returns html and I haven't found a way to modify its functionality (if I could, I would have already set the magic header Access-control-allow-origin: *). So I decided to write a small console app in C#. It has to be run as Admin to work properly, otherwise it trolls :D an exception. Here is some code:

    // Create a listener.
            HttpListener listener = new HttpListener();
            // Add the prefixes.
            //foreach (string s in prefixes)
            //{
            //    listener.Prefixes.Add(s);
            //}
            listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
            //because the printer is accessible only within the LAN (no portforwarding)
            listener.Start();
            Console.WriteLine("Listening...");
            // Note: The GetContext method blocks while waiting for a request. 
            HttpListenerContext context;
            string urlForRequest = "";
    
            HttpWebRequest requestForPage = null;
            HttpWebResponse responseForPage = null;
            string responseForPageAsString = "";
    
            while (true)
            {
                context = listener.GetContext();
                HttpListenerRequest request = context.Request;
                urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
                Console.WriteLine(urlForRequest);
    
                //Request for the html page:
                requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
                responseForPage = (HttpWebResponse)requestForPage.GetResponse();
                responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();
    
                // Obtain a response object.
                HttpListenerResponse response = context.Response;
                // Send back the response.
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
                // Get a response stream and write the response to it.
                response.ContentLength64 = buffer.Length;
                response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
                System.IO.Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                // You must close the output stream.
                output.Close();
                //listener.Stop();
    

    All the user needs to do is run that console app as Admin. I know it is way too ... frustrating and complicated, but it is sort of a workaround to the Domain Policy problem in case you cannot modify the server in any way.

    edit: from js I make a simple ajax call:

    $.ajax({
                    type: 'POST',
                    url: 'http://LAN_IP:1234/http://google.com',
                    success: function (data) {
                        console.log("Success: " + data);
                    },
                    error: function (e) {
                        alert("Error: " + e);
                        console.log("Error: " + e);
                    }
                });
    

    The html of the requested page is returned and stored in the data variable.

提交回复
热议问题