HTTP错误415,我错在哪里?

5 投票
3 回答
25580 浏览
提问于 2025-04-16 13:07

我正在发送一个SOAP POST请求,但在执行时遇到了一个错误:“HTTPError: HTTP Error 415: 不支持的媒体类型”,这个错误出现在我执行这行代码时:response = urllib2.urlopen(req)

data = """<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <AutotaskIntegrations xmlns="http://autotask.net/ATWS/v1_5/">
      <PartnerID>1</PartnerID>
    </AutotaskIntegrations>
  </soap:Header>
  <soap:Body>
    <getThresholdAndUsageInfo xmlns="http://autotask.net/ATWS/v1_5/">
    </getThresholdAndUsageInfo>
  </soap:Body>
</soap:Envelope>"""

headers = {
    'Content-Type': 'application/soap+xml; charset=utf-8'
    'Host: "webservices.autotask.net"'
    'Content-Type: text/xml; charset=utf-8'
    'Content-Length: len(data)'
    'SOAPAction: "http://autotask.net/ATWS/v1_5/getThresholdAndUsageInfo"'
    }

site = 'https://webservices.autotask.net/atservices/1.5/atws.asmx'
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='webservices.autotask.net',
                          uri=site,
                          user='george.lastname@domain.com',
                          passwd='mypw')
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
page = urllib2.urlopen(site)                            #errors out 415 here
req = urllib2.Request(site, data, headers)
response = urllib2.urlopen(req)

我哪里做错了呢?谢谢!

3 个回答

2

在你的请求头里,有两个地方写了Content-Type。

你发送的消息使用的是SOAP 1.1的命名空间,这样就和第二个Content-Type(text/xml)匹配了。不过根据错误信息来看,我猜第一个Content-Type(application/soap+xml),也就是SOAP 1.2的格式,实际上是被发送到了服务器。你可以把第一个Content-Type去掉,这样如果你的服务器确实是想要SOAP 1.1的消息,就应该能解决问题。

4

我知道这个问题已经解决了,但我花了很长时间才找到这个错误的解决办法,所以想把这个方法分享出来,免得其他人也遇到和我一样的问题。在搜索了几个小时后,我发现我正在查看的文件使用的是SOAP v1.2。这可能会造成问题,因为据我所知,Suds还不支持v1.2。

我找到了一种变通方法,可以让Suds认为它正在使用v1.2,具体方法可以在这里找到:SOAP 1.2 python client。我相信这个方法并不适合所有人,因为415错误可能由很多不同的原因引起,但对我来说有效,而这个问题的解决方案非常少,所以我们能分享的越多越好。下面是我用的代码(那页上有几个可能的解决方案)。

from suds.client import Client
from suds.bindings import binding
import logging

USERNAME = 'username'
PASSWORD = 'password'

# Just for debugging purposes.
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)

# Telnic's SOAP server expects a SOAP 1.2 envelope, not a SOAP 1.1 envelope
# and will complain if this hack isn't done.
binding.envns = ('SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')
client = Client('client.wsdl',
    username=USERNAME,
    password=PASSWORD,
    headers={'Content-Type': 'application/soap+xml'})

# This will now work just fine.
client.service.someRandomMethod()
7

headers这个字典里,Content-Length的值看起来不对。

'Content-Length: len(data)' 

还有其他一些值也有问题。

我会用下面的方式来修复它:

headers = {
    'Content-Type': 'application/soap+xml; charset=utf-8',
    'Host': 'webservices.autotask.net',
    'Content-Length': len(data),
    'SOAPAction': 'http://autotask.net/ATWS/v1_5/getThresholdAndUsageInfo'
}

撰写回答