Предполетная CORS проблема с HTTP-сервером javascript и python

У меня возникли проблемы с получением следующего java-скрипта.

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 + "
" + thrownError);  
    }
});

Я изменил следующий скрипт python для сервера

"""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>
" % self.path)
        f.write("<h2>Directory listing for %s</h2>
" % self.path)
        f.write("<hr>
<ul>
")
        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>
' % (linkname, displayname))
        f.write("</ul>
<hr>
")
        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
        (e.g. 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()

Я получаю следующую ошибку от отладчика Chrome. (Я просто хочу, чтобы это работало с Chrome)

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.

Следующее - это то, что я получаю от Fiddler Inspector

Начальные заголовки запроса

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

Начальные заголовки ответов

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

Заголовки запроса предполетной защиты

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 (не 100% уверен, что если это предполетный ответ, но это ответ на указанный выше запрос)

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>

Прямой звонок со следующим URL-адресом и правильным именем пользователя и паролем для веб-сайта для получения точной информации работает полностью.

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

Это похоже на то, что связано с аутентификацией, даже несмотря на то, что отладчик Google говорит, что вызов перед полетом имеет проблему с получением заголовка «Access-Control-Allow-Origin». Я мог ошибаться и мог пропустить что-то и не смог заставить заголовок Origin работать.

Я попытался добавить дополнительные методы в Access-Control-Allow-Methods, такие как OPTIONS и POST, но это не имело никакого значения.

Любые предложения или помощь были бы замечательными.

,

javascript,python,ajax,cors,preflight,

0

Ответов: 0

Предполетная CORS проблема с HTTP-сервером javascript и python

У меня возникли проблемы с получением следующего java-скрипта.

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 + "
" + thrownError);  
    }
});

Я изменил следующий скрипт python для сервера

"""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>
" % self.path)
        f.write("<h2>Directory listing for %s</h2>
" % self.path)
        f.write("<hr>
<ul>
")
        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>
' % (linkname, displayname))
        f.write("</ul>
<hr>
")
        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
        (e.g. 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()

Я получаю следующую ошибку от отладчика Chrome. (Я просто хочу, чтобы это работало с Chrome)

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.

Следующее - это то, что я получаю от Fiddler Inspector

Начальные заголовки запроса

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

Начальные заголовки ответов

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

Заголовки запроса предполетной защиты

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 (не 100% уверен, что если это предполетный ответ, но это ответ на указанный выше запрос)

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>

Прямой звонок со следующим URL-адресом и правильным именем пользователя и паролем для веб-сайта для получения точной информации работает полностью.

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

Это похоже на то, что связано с аутентификацией, даже несмотря на то, что отладчик Google говорит, что вызов перед полетом имеет проблему с получением заголовка «Access-Control-Allow-Origin». Я мог ошибаться и мог пропустить что-то и не смог заставить заголовок Origin работать.

Я попытался добавить дополнительные методы в Access-Control-Allow-Methods, такие как OPTIONS и POST, но это не имело никакого значения.

Любые предложения или помощь были бы замечательными.

,

00JavaScript, Python, AJAX, CORS, предполетный,
Похожие вопросы