---
title: "解决ie8的跨站请求问题"
url: "https://lerry.me/post/2013/06/ie8-cross-domain-request-issue"
date: 2013-06-27T14:36:00.000Z
updated: 2026-08-31T08:41:39.042Z
tags:
  - "IE"
  - "XDomainRequest"
  - "跨站提交"
  - "Access-Control-Allow-Origin"
  - "Tornado"
language: zh-CN
---

# 解决ie8的跨站请求问题

由于工作的需要，最近开始学前端。果然实践出真知，感觉这几天学到了不少东西。

需求是这样的，需要在主站上挂载一个BBS，而BBS服务是在另一个域名下的，数据的提交和请求都涉及到跨站。

jsonp是解决这类问题的一种常用方法，但是这种方法有个缺点，由于jsonp 实际是用的 GET 请求，参数是编码在URL中的，而浏览器对URL支持的长度是有限的，最坑爹的是 IE，其支持的长度仅为 2083 字符，过长的URL也会被nginx拒绝的。内容稍长一些，这个限制就会达到，于是只能使用POST了。

最后采用的办法是，通过给服务器返回值中加上“Access-Control-Allow-Origin” header 来允许跨站请求。这个很快实现了，在Chrome（我最喜欢的浏览器）和Firefox下测试通过，但是IE8就不行了，原因是ie8不支持XMLHttpRequest，导致ajax请求无效，好在它支持另一种协议，XDomainRequest，通过这个扩展 [jQuery-ajaxTransport-XDomainRequest](https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest)，代码不用修改一行，就可以正常在 IE8 下运行了。这时，GET请求可以用了，但是在测试发帖时却发现，服务器获取不到POST的内容，通过IE的开发者工具模拟IE8，IE9均无法正常POST，IE10却又可以了，我们将IE8和IE10的请求头作对比，发现IE8发出的请求没有定义Content-Type，我们的服务器是用的是Tornado框架，经过翻阅源码，找到了这里

```python
def parse_body_arguments(content_type, body, arguments, files):
    """Parses a form request body.

    Supports ``application/x-www-form-urlencoded`` and
    ``multipart/form-data``.  The ``content_type`` parameter should be
    a string and ``body`` should be a byte string.  The ``arguments``
    and ``files`` parameters are dictionaries that will be updated
    with the parsed contents.
    """
    if content_type.startswith("application/x-www-form-urlencoded"):
        uri_arguments = parse_qs_bytes(native_str(body), keep_blank_values=True)
        for name, values in uri_arguments.items():
            if values:
                arguments.setdefault(name, []).extend(values)
    elif content_type.startswith("multipart/form-data"):
        fields = content_type.split(";")
        for field in fields:
            k, sep, v = field.strip().partition("=")
            if k == "boundary" and v:
                parse_multipart_form_data(utf8(v), body, arguments, files)
                break
        else:
            gen_log.warning("Invalid multipart/form-data")
```

原来，tornado对不同Content-Type的POST内容解析方法是不一样的，到这里，问题就解决了，可以在ajax请求时自己附带上Content-Type值（未测试），或者 hack Tornado，设置默认的Content-Type。最后说一句，珍爱生命，远离IE。
