Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 415异常Cherrypy Web服务_Python_Ajax_Cross Domain_Cherrypy - Fatal编程技术网

Python 415异常Cherrypy Web服务

Python 415异常Cherrypy Web服务,python,ajax,cross-domain,cherrypy,Python,Ajax,Cross Domain,Cherrypy,我正在尝试构建一个Cherrypy/Python Web服务。我已经花了一整天的时间研究如何使跨域ajax请求成为可能。这终于奏效了,但现在我有了下一个问题。我想我已经知道了解决方案,但我不知道如何实现它。问题是,当我发送ajax请求时,Cherrypy服务器响应为: 415 Unsupported Media Type Expected an entity of content type application/json, text/javascript Traceback (most r

我正在尝试构建一个Cherrypy/Python Web服务。我已经花了一整天的时间研究如何使跨域ajax请求成为可能。这终于奏效了,但现在我有了下一个问题。我想我已经知道了解决方案,但我不知道如何实现它。问题是,当我发送ajax请求时,Cherrypy服务器响应为:

415 Unsupported Media Type

Expected an entity of content type application/json, text/javascript

Traceback (most recent call last):  File "/Library/Python/2.7/site-packages/cherrypy/_cprequest.py", line 663, in respond    self.body.process()  File "/Library/Python/2.7/site-packages/cherrypy/_cpreqbody.py", line 996, in process    super(RequestBody, self).process()  File "/Library/Python/2.7/site-packages/cherrypy/_cpreqbody.py", line 538, in process    self.default_proc()  File "/Library/Python/2.7/site-packages/cherrypy/_cperror.py", line 411, in __call__    raise selfHTTPError: (415, u'Expected an entity of content type application/json, text/javascript')    
我找到并尝试测试的解决方案是将以下行添加到配置中:

'tools.json_in.force': False
因此,我尝试在以下代码中实现它:

import cherrypy
import json
import sys

class RelatedDocuments:

def index(self):
    return "Hello World!"

@cherrypy.tools.json_out()
@cherrypy.tools.json_in()
def findRelated(self, **raw):
    #Get JSON message form request
    request = cherrypy.request.json
    result = []

    #SOME CODE...

    return result;

# Expose the index method through the web. CherryPy will never
# publish methods that don't have the exposed attribute set to True.
index.exposed = True
findRelated.exposed = True

def CORS():
    cherrypy.response.headers["Access-Control-Allow-Origin"] = "*"

import os.path
tutconf = os.path.join(os.path.dirname(__file__), 'webserver.conf')
config = {
    'global': {
        'server.socket_host':'127.0.0.1',
        'server.socket_port': 8080,
        'log.error_file' : 'Web.log',
        'log.access_file' : 'Access.log'
    },
    '/': {
        'tools.CORS.on': True
    }
}

if __name__ == '__main__':
    cherrypy.tools.CORS = cherrypy.Tool('before_finalize', CORS)

    cherrypy.quickstart(RelatedDocuments(),config=config)
我在tools.CORS.on行下添加了配置行,但这不起作用。接下来我尝试了这个:

cherrypy.config.update({
    'tools.json_in.force': False,
});
eiter不起作用。接下来,我尝试在findRelated方法上方实现此功能:

@cherrypy.config(**{'tools.json_in.force': False})

所有的实现都给了我500个错误,如果有人能帮助我,我真的很感激。提前谢谢

一般来说,如果你选择了一个工具,那么你最好使用它,而不是与之对抗。CherryPy告诉您,对于JSON输入,它希望请求具有
application/JSON
text/javascript
内容类型

以下是代码:

force
除了删除现有的车身处理器外,没有其他功能。如果将
force
设置为
False
,则需要告诉CherryPy如何处理发送给它的请求正文

或者,最好使用CherryPy并告诉它正确的内容类型。使用jQuery,它非常简单:

 jQuery.ajax({
    'type'        : 'POST',
    'dataType'    : 'JSON',
    'contentType' : 'application/json',
    'url'         : '/findRelated',
    'data'        : JSON.stringify({'foo': 'bar'})
 });

我意识到这个问题实际上是关于。CORS对于简单的CORS请求,满足以下条件:

  • 方法:
    GET
    HEAD
    POST
  • 标题:
    接受
    接受语言
    内容语言
    内容类型
  • 内容类型标题值:
    application/x-www-form-urlencoded
    multipart/form data
    text/plain
否则CORS请求并不简单,在实际请求之前使用飞行前选项请求以确保其符合条件。这是

因此,如果您希望保持简单,您可能希望恢复到正常的
application/x-www-form-urlencoded
。否则,您需要正确处理飞行前请求。下面是一个工作示例(不要忘记添加
localhost
alias)

#/usr/bin/env python
#-*-编码:utf-8-*-
'''
在/etc/hosts中添加本地主机别名“proxy”。
'''
进口樱桃
配置={
“全球”:{
'server.socket_host':'127.0.0.1',
'server.socket_port':8080,
“服务器线程池”:8
}
}
def cors():
如果cherrypy.request.method=='OPTIONS':
#预对齐请求
#看http://www.w3.org/TR/cors/#cross-原点-请求-带-飞行前-0
cherrypy.response.headers['Access-Control-Allow-Methods']='POST'
cherrypy.response.headers['Access-Control-Allow-headers']='content-type'
cherrypy.response.headers['Access-Control-Allow-Origin']='*'
#告诉CherryPy不要避开正常的处理程序
返回真值
其他:
cherrypy.response.headers['Access-Control-Allow-Origin']='*'
cherrypy.tools.cors=cherrypy.\u cptools.HandlerTool(cors)
类应用程序:
@樱桃树
def索引(自):
返回“”'
CORS AJAX JSON请求
$(文档).ready(函数()
{
$('button')。在('click',function()上
{
$.ajax({
'type':'POST',
“数据类型”:“JSON”,
“contentType”:“application/json”,
“url”:”http://proxy:8080/endpoint',
'data':JSON.stringify({'foo':'bar'}),
“成功”:函数(响应)
{
控制台日志(响应);
}
});
})
});
请求
'''
@樱桃树
@cherrypy.config(**{'tools.cors.on':True})
@json_in()中的cherrypy.tools.json
@cherrypy.tools.json_out()
def端点(自身):
data=cherrypy.request.json
返回数据。items()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
cherrypy.quickstart(App(),“/”,config)

是的,我知道……我已经看到了这个文件,我的内容类型首先是application/json。但后来我的HTTP请求从POST更改为OPTIONS方法,但我显式地将该方法设置为POST。我找到了一些关于这方面的信息,可能是跨域ajax请求,但找不到解决方案。我只是想建立一个快速原型,所以我找到了另一个解决方案,希望我能暂时快速解决这个问题。非常感谢你,你让我度过了美好的一天!现在一切都很好,从来没有听说过飞行前的请求。
 jQuery.ajax({
    'type'        : 'POST',
    'dataType'    : 'JSON',
    'contentType' : 'application/json',
    'url'         : '/findRelated',
    'data'        : JSON.stringify({'foo': 'bar'})
 });
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Add localhost alias, `proxy` , in /etc/hosts.
'''


import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}


def cors():
  if cherrypy.request.method == 'OPTIONS':
    # preflign request 
    # see http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
    cherrypy.response.headers['Access-Control-Allow-Methods'] = 'POST'
    cherrypy.response.headers['Access-Control-Allow-Headers'] = 'content-type'
    cherrypy.response.headers['Access-Control-Allow-Origin']  = '*'
    # tell CherryPy no avoid normal handler
    return True
  else:
    cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'

cherrypy.tools.cors = cherrypy._cptools.HandlerTool(cors)


class App:

  @cherrypy.expose
  def index(self):
    return '''<!DOCTYPE html>
      <html>
      <head>
      <meta content='text/html; charset=utf-8' http-equiv='content-type'>
      <title>CORS AJAX JSON request</title>
      <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
      <script type='text/javascript'>
        $(document).ready(function()
        {
          $('button').on('click', function()
          {
            $.ajax({
              'type'        : 'POST',
              'dataType'    : 'JSON',
              'contentType' : 'application/json',
              'url'         : 'http://proxy:8080/endpoint',
              'data'        : JSON.stringify({'foo': 'bar'}),
              'success'     : function(response)
              {
                console.log(response);  
              }
            });
          })
        });
      </script>
      </head>
      <body>
        <button>make request</button>
      </body>
      </html>
    '''

  @cherrypy.expose
  @cherrypy.config(**{'tools.cors.on': True})
  @cherrypy.tools.json_in()
  @cherrypy.tools.json_out()
  def endpoint(self):
    data = cherrypy.request.json
    return data.items()


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)