Preflight CORS Ausgabe mit Javascript und Python Basis http Server

Ich habe Schwierigkeiten, das folgende Java-Skript zu arbeiten.

window.onload = function() { mycallback(dataParm); }; function mycallback(data) { console.log(data); return true; } var xhr = $.ajax({ url: connectionUri, dataType: 'json', type: 'GET', headers: { "Authorization":"Basic " + btoa(userName + ":" + password) }, success: function (data) { console.log("In Success"); document.getElementById("id01").innerHTML = data; }, error: function (xhr, ajaxOptions, thrownError) { console.log("Connection error: " + xhr.responseText + "\n" + thrownError); } }); 

Ich habe das folgende Python-Skript für den Server geändert

 """Preflight CORS HTTP Server. This is modified version of SimpleHTTPRequestHandler This module builds on BaseHTTPServer by implementing the standard GET and HEAD requests in a fairly straightforward manner. """ __version__ = "1.0" __all__ = ["PreflightCORSHandler"] import os import posixpath import BaseHTTPServer import urllib import cgi import shutil import mimetypes from StringIO import StringIO class PreflightCORSHandler(BaseHTTPServer.BaseHTTPRequestHandler): """PreflightCORS HTTP request handler with GET and HEAD commands. This serves files from the current directory and any of its subdirectories. It assumes that all files are plain text files unless they have the extension ".html" in which case it assumes they are HTML files. The GET and HEAD requests are identical except that the HEAD request omits the actual contents of the file. """ server_version = "PreflightCORSHTTP/" + __version__ def do_GET(self): """Serve a GET request.""" f = self.send_head() if f: self.copyfile(f, self.wfile) f.close() def do_OPTIONS(self): self.send_response(200, "ok") self.send_header("Access-Control-Allow-Origin", "http://localhost:8889") self.send_header("Access-Control-Allow-Credentials", "true") self.send_header("Access-Control-Allow-Methods", "GET") self.send_header("Access-Control-Allow-Headers", "dataType, accept, authorization") def do_HEAD(self): """Serve a HEAD request.""" f = self.send_head() if f: f.close() def send_head(self): """Common code for GET and HEAD commands. This sends the response code and MIME headers. Return value is either a file object (which has to be copied to the outputfile by the caller unless the command was HEAD, and must be closed by the caller under all circumstances), or None, in which case the caller has nothing further to do. """ path = self.translate_path(self.path) f = None if os.path.isdir(path): for index in "index.html", "index.htm": index = os.path.join(path, index) if os.path.exists(index): path = index break else: return self.list_directory(path) ctype = self.guess_type(path) if ctype.startswith('text/'): mode = 'r' else: mode = 'rb' try: f = open(path, mode) except IOError: self.send_error(404, "File not found") return None self.send_response(200) self.send_header("Content-type", ctype) self.send_header("Access-Control-Allow-Origin", "http://localhost:8889") self.send_header("Access-Control-Allow-Credentials", "true") self.send_header("Access-Control-Allow-Methods", "GET") self.send_header("Access-Control-Allow-Headers", "dataType, accept, authorization") self.end_headers() return f def list_directory(self, path): """Helper to produce a directory listing (absent index.html). Return value is either a file object, or None (indicating an error). In either case, the headers are sent, making the interface the same as for send_head(). """ try: list = os.listdir(path) except os.error: self.send_error(404, "No permission to list directory") return None list.sort(lambda a, b: cmp(a.lower(), b.lower())) f = StringIO() f.write("<title>Directory listing for %s</title>\n" % self.path) f.write("<h2>Directory listing for %s</h2>\n" % self.path) f.write("<hr>\n<ul>\n") for name in list: fullname = os.path.join(path, name) displayname = linkname = name = cgi.escape(name) # Append / for directories or @ for symbolic links if os.path.isdir(fullname): displayname = name + "/" linkname = name + "/" if os.path.islink(fullname): displayname = name + "@" # Note: a link to a directory displays with @ and links with / f.write('<li><a href="%s">%s</a>\n' % (linkname, displayname)) f.write("</ul>\n<hr>\n") f.seek(0) self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() return f def translate_path(self, path): """Translate a /-separated PATH to the local filename syntax. Components that mean special things to the local file system (eg drive or directory names) are ignored. (XXX They should probably be diagnosed.) """ path = posixpath.normpath(urllib.unquote(path)) words = path.split('/') words = filter(None, words) path = os.getcwd() for word in words: drive, word = os.path.splitdrive(word) head, word = os.path.split(word) if word in (os.curdir, os.pardir): continue path = os.path.join(path, word) return path def copyfile(self, source, outputfile): """Copy all data between two file objects. The SOURCE argument is a file object open for reading (or anything with a read() method) and the DESTINATION argument is a file object open for writing (or anything with a write() method). The only reason for overriding this would be to change the block size or perhaps to replace newlines by CRLF -- note however that this the default server uses this to copy binary data as well. """ shutil.copyfileobj(source, outputfile) def guess_type(self, path): """Guess the type of a file. Argument is a PATH (a filename). Return value is a string of the form type/subtype, usable for a MIME Content-type header. The default implementation looks the file's extension up in the table self.extensions_map, using text/plain as a default; however it would be permissible (if slow) to look inside the data to make a better guess. """ base, ext = posixpath.splitext(path) if self.extensions_map.has_key(ext): return self.extensions_map[ext] ext = ext.lower() if self.extensions_map.has_key(ext): return self.extensions_map[ext] else: return self.extensions_map[''] extensions_map = mimetypes.types_map.copy() extensions_map.update({ '': 'application/octet-stream', # Default '.py': 'text/plain', '.c': 'text/plain', '.h': 'text/plain', }) def test(HandlerClass = PreflightCORSHandler, ServerClass = BaseHTTPServer.HTTPServer): BaseHTTPServer.test(HandlerClass, ServerClass) if __name__ == '__main__': test() 

Ich bekomme den folgenden Fehler von Chrome Debugger. (Ich möchte das einfach nur mit Chrome arbeiten)

 XMLHttpRequest cannot load https://services.yesenergy.com/PS/rest/constraint/HOURLY/RTPD/CAISO.json?startdate=2016-05-01. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8889' is therefore not allowed access. The response had HTTP status code 401. 

Das Folgende ist, was ich von Fiddler Inspector bekomme

Anfängliche Header

 GET http://localhost:8889/test.html HTTP/1.1 Host: localhost:8889 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 

Initial Respond Headers

 HTTP/1.0 200 OK Server: PreflightCORSHTTP/1.0 Python/2.7.6 Date: Wed, 13 Jul 2016 01:38:15 GMT Content-type: text/html Access-Control-Allow-Origin: http://localhost:8889 Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET Access-Control-Allow-Headers: dataType, accept, authorization 

Preflight Anforderungsüberschriften

 OPTIONS https://services.yesenergy.com/PS/rest/constraint/HOURLY/RTPD/CAISO.json?startdate=2016-05-01 HTTP/1.1 Host: services.yesenergy.com Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Access-Control-Request-Method: GET Origin: http://localhost:8889 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36 Access-Control-Request-Headers: dataType, accept, authorization Accept: */* Referer: http://localhost:8889/test.html Accept-Encoding: gzip, deflate, sdch, br Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 

Preflight Respond (nicht 100% sicher, ob das der Preflight reagiert, aber es ist die Antwort auf die Anfrage oben)

 HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="Spring Security Application" Content-Type: text/html;charset=utf-8 Content-Language: en Content-Length: 1059 Date: Wed, 13 Jul 2016 01:38:15 GMT Server: Apache <html><head><title>Apache Tomcat/7.0.x - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Full authentication is required to access this resource</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Full authentication is required to access this resource</u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.x</h3></body></html> 

Ein direkter Anruf mit der folgenden URL und korrekten Benutzernamen und Passwort auf der Website für die exakt gleichen Informationen funktioniert ganz gut.

 https://username:password@services.yesenergy.com/PS/rest/constraint/HOURLY/RTPD/CAISO.json?startdate=2016-05-01 

Es fühlt sich an wie etwas, das mit der Authentifizierung zusammenhängt, obwohl der Google-Debugger sagt, dass der Preflight-Aufruf das Problem hat, "Access-Control-Allow-Origin" -Header zu erhalten. Ich könnte mich irren und kann etwas verpasst haben und konnte den Origin-Header nicht mehr arbeiten.

Ich habe versucht, zusätzliche Methoden zu Access-Control-Allow-Methoden wie OPTIONEN und POST hinzuzufügen, aber es hat keinen Unterschied gemacht.

Irgendwelche Vorschläge oder Hilfe wäre großartig.

.

One Solution collect form web for “Preflight CORS Ausgabe mit Javascript und Python Basis http Server”

Ich hatte das gleiche Problem auch! (Cross Origin Resource Sharing) ist ein Header, der in der Apache httpd.conf oder apache.conf oder .htaccess Konfigurationsdatei vorhanden sein muss. Wenn du auf NGINX bist, musst du die Datei defaults.conf oder nginx.conf bearbeiten. Es macht es grundsätzlich so, dass der Webserver HTTP-Anfragen von anderen Orten als seiner eigenen Domain akzeptiert. Der "echte" Weg, um es zu beheben ist, indem er tatsächlich in den Webserver (via ssh) geht und die anwendbare .conf bearbeitet, um diesen Header einzuschließen. Wenn du auf Apache bist, würdest du Header set Access-Control-Allow-Origin "*" am Anfang der Datei hinzufügen. Nachdem Sie dies tun, starten Sie Apache neu, um sicherzustellen, dass Ihre Änderungen gespeichert werden (Service httpd Neustart). Wenn Sie auf NGINX sind, verwenden Sie diese Konfiguration:

  # # Wide-open CORS config for nginx # location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; # # Om nom nom cookies # add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } } 

Jetzt weiß ich nicht, ob du Zugriff auf den Webserver hast. Wenn du tust, großartig! Mach einfach das Zeug, das ich an die Spitze gebe. Ansonsten wird es heiss.

Eine Ihrer Optionen ist, http://www.whateverorigin.org/ zu benutzen. Es umgibt CORS und ruft die Daten effektiv ab. Um es zu benutzen, würden Sie laufen:

 $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://google.com') + '&callback=?', function(data){ alert(data.contents); }); 

Dies ruft die Antwort unabhängig von den auf dem Webserver vorhandenen CORS ab.

Wenn Sie nicht möchten, dass Sie Ihren vorhandenen Code ändern und Sie Google Chrome verwenden, gibt es einen Weg um dieses CORS-Problem. Eine Sache, die Sie tun können, ist, diese Browser-Erweiterung zu installieren: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?utm_source=plus und Sie können CORS umgehen und Ihr Programm ausführen.

Hoffe das funktioniert für dich!

Python ist die beste Programmiersprache der Welt.