CORS服务器端与客户端?为啥一个工作,但另一个 - 不?

Posted

技术标签:

【中文标题】CORS服务器端与客户端?为啥一个工作,但另一个 - 不?【英文标题】:CORS server-side vs client-side? Why one works, but another - doesn't?CORS服务器端与客户端?为什么一个工作,但另一个 - 不? 【发布时间】:2018-02-12 16:31:17 【问题描述】:

我不确定我是否理解这一点。我可以编写一个简单的服务器端代码来抓取任何网站的 html 内容。在我的本地 PC 或任何主机上运行它并从任何网站检索任何页面。但这不能通过 javascript 完成?

远程主机怎么可能知道什么样的应用程序正在发出请求?出于安全目的,不允许跨源请求?为什么我可以使用服务器端代码发出完全相同的请求?并在任何地方本地或远程运行此代码?下面是一个从 Weather 站点获取 HTML 页面内容的简单示例,效果很好。但我不能在 JavaScript 代码中做到这一点?没有意义。

public static class WeatherManager

    private static HtmlDocument document = new HtmlDocument();

    public static MyWeather GetWeather()
    
        try
        
            var web = new HtmlWeb();
            document = web.Load("http://www.weatheroffice.gc.ca/city/pages/on-143_metric_e.html");
        
        catch (Exception ex)
        
            throw new Exception("Weather is not loaded");
        

        var mainContent = document.DocumentNode.SelectSingleNode("//*[@id='mainContent']");
        var nownode = mainContent.SelectSingleNode("//section[1]/details/div/div");
        var forecastnodes = mainContent.SelectNodes("//section[2]/details/table[1]/tr[2]/td");

        // Do some processing....
    

但是当我尝试从 Angular(或任何我认为的 JS lib)发出类似的请求时

getWeatherForecast() 
    const url = 'https://weather.gc.ca/city/pages/on-143_metric_e.html';
    return this.$http.get(url);

我得到了这样的东西

我知道... CORS 好的,但如果它是出于安全目的,我怎么能以我喜欢的方式发出这些 CORS 请求,例如上面的服务器端代码?

【问题讨论】:

【参考方案1】:

但这不能通过 javaScript 完成?

是的,它可以——只是不能在浏览器上。您可以在 Node 或 JVM 中使用 JavaScript 发出请求(因为 JVM 通过javax.script 支持 JavaScript),或在 Windows 上的 Metro 应用程序等中。

远程主机怎么可能知道什么样的应用程序正在发出请求?

它没有。 浏览器执行同源策略,而不是服务器。

为什么我可以使用服务器端代码发出完全相同的请求?

...

...但是如果它是出于安全目的,我怎么能以我喜欢的方式发出这些 CORS 请求,例如上面的服务器端代码?

因为您的服务器端代码无法访问潜在机密的客户端信息。来自the Wikipedia article on the SOP:

同源策略有助于保护使用经过身份验证的会话的网站。以下示例说明了在没有同源策略的情况下可能出现的潜在安全风险。假设用户正在访问银行网站并且没有注销。然后,用户转到另一个站点,该站点在后台运行一些恶意 JavaScript 代码,该代码从银行站点请求数据。由于用户仍在银行网站上登录,恶意代码可以做任何用户在银行网站上可以做的事情。例如,它可以获取用户最近交易的列表、创建新交易等。这是因为浏览器可以根据银行站点的域向银行站点发送和接收会话 cookie。

访问恶意站点的用户会认为他或她正在访问的站点无法访问银行会话 cookie。虽然 JavaScript 确实无法直接访问银行会话 cookie,但它仍然可以使用银行站点的会话 cookie 向银行站点发送和接收请求。因为脚本基本上可以像用户一样做,即使是银行网站的 CSRF 保护也不会有效。

【讨论】:

以上是关于CORS服务器端与客户端?为啥一个工作,但另一个 - 不?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Security 身份验证会导致 CORS 错误

为啥使用 AWS CloudFront 时出现 CORS 客户端错误?

CORS:为啥我的浏览器不发送 OPTIONS 预检请求?

在服务器端的 IIS 上使用 PHP 并在客户端使用 Angular 4 时出现 CORS 错误

WCF 上的 CORS - 为啥在请求来自客户端机器时指定 Web 服务器?

为啥我的 CORS 应用程序无法识别我的会话?