【问题标题】:Access to fetch from origin localhost blocked by CORS policy, post using ajax does not. Why?访问被 CORS 策略阻止的从 localhost 获取的访问权限,使用 ajax 发布不会。为什么?
【发布时间】:2020-02-01 13:45:48
【问题描述】:

这不是 CORS 的问题,因此不要建议使用浏览器插件或更改服务器代码的解决方法。我只是想了解为什么 ajax post 有效,而 fetch post 无效!

目前使用 jQuery 和 ajax 进行一些获取和发布。使用 ajax 从 localhost 发出 post 请求可以正常工作,而类似这样的请求没有任何问题:

$.ajax({
    type: 'POST',
    url: 'https://api.example.com/endpoint',
    cache: false,
    data: {
        moment: {
            parameters: 'some params',
            url: 'https://example.com',
            caption: 'caption'
        }
    }
})

我决定开始使用 fetch 而不是 ajax,但是从相同的 localhost 条件执行“看起来”像相同请求的操作失败并显示错误消息

从源“http://localhost”获取“http://api.example.com/endpoint”的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。

获取请求类似于以下内容:

fetch('https://api.example.com/endpoint', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    cache: 'no-cache',
    body: JSON.stringify({
        moment: {
            parameters: 'some params',
            url: 'https://example.com',
            caption: 'caption'
        }
    })
})

我只是想了解 jQuery 是如何解决这个问题的?我一直在查看 github 上的源代码,并没有看到任何特别之处。还是 XMLHttpRequest 没有的 fetch api 中添加了限制?

编辑:

在网络选项卡中,ajax 请求如下所示:

General
    Request URL: https://api.example.com/endpoint
    Request Method: POST
    Status Code: 200 OK
    Remote Address: ip:80
    Referrer Policy: no-referrer-when-downgrade

Headers
    Accept: */*
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    DNT: 1
    Referer: http://localhost/index.html?target=...
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

虽然获取请求看起来像:

General
    Request URL: https://api.example.com/endpoint
    Referrer Policy: no-referrer-when-downgrade

Headers
    Content-Type: application/json
    DNT: 1
    Referer: http://localhost/index.html?target=...
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

将所有这些标头从 ajax 添加到 fetch 请求没有任何区别。

【问题讨论】:

  • jQuery 在绕过 CORS 方面并没有什么特别之处,因为这在技术上是不可能的。你 100% 确定 jQuery 请求没有被缓存吗?理论上,如果有 CORS 限制,这些请求都不会起作用。
  • “网络”选项卡中的这两个请求是什么样的?例如,标题有什么不同吗?
  • @RoryMcCrossan 是的,我确定。在测试不同的请求之间,我已经多次清除浏览器中的所有缓存。
  • @mbojko 感谢您的建议,我已经用两个请求的内容更新了我的问题。
  • 它们看起来像响应头,你有请求头吗?

标签: javascript jquery ajax fetch-api


【解决方案1】:

问题最终是三重的。

  1. Rory 评论说,jQuery 不会对 CORS 进行任何更改。这是我的错误,我有两个端点,一个用于接受跨域调用的开发,一个不接受,它们看起来非常相似并且行为相同,但 CORS 除外。
  2. 如果没有提供,jQuery 默认将Content-Type 标头设置为application/x-www-form-urlencoded; charset=UTF-8。 Fetch 不会默认任何特定的内容。
  3. jQuery 还将自动发送的数据解析为 php 和 ruby​​ 后端接受的格式。看起来像

这个:

moment[parameters]: value
moment[url]: value
moment[caption]: value

所以我不得不编写自己版本的 jQuery 的 $.param() 函数,因为我还没有在 Javascript 中找到任何可以编码子对象的东西。

【讨论】:

    猜你喜欢
    • 2019-04-11
    • 2021-08-14
    • 2021-04-15
    • 2021-05-12
    • 2020-07-29
    • 2020-10-07
    • 2019-11-01
    • 2021-04-01
    • 2021-07-20
    相关资源
    最近更新 更多