如何从 https 网站获取 http 内容?

Posted

技术标签:

【中文标题】如何从 https 网站获取 http 内容?【英文标题】:How do I get http content from a https website? 【发布时间】:2020-07-24 19:37:44 【问题描述】:

当我从安全 url 请求时,我收到“https://www.google.com 的 Http 失败响应:0 未知错误”。

我正在尝试测试我的 ionic/angular 移动应用。当我尝试使用 http 请求时,我遇到了 android 9 的问题,但 Android 7 运行良好。无论如何,我需要将我的后端设置为公共 https 服务器。所以现在我正在使用 https 请求进行测试,并且 7 和 9 Android 版本都不起作用。

我正在使用 Angular 7,

"@ionic/angular": "^4.6.1",
"@ionic-native/core": "^5.0.0",
"rxjs": "~6.5.1"

我做了这些小函数是为了让我的问题更简单。

在我的 html 文件中,我有以下代码:

我的文件.html

  <ion-button
          (click)="onStartTest()"
  >Click me</ion-button>
  <p id="testme"></p>

myFile.page.ts

  onStartTest() 
    this.taskService.onTest().subscribe(result => 
      document.getElementById('testme').innerText = 'result ' + result;
      console.log(result);

    , error => 
      document.getElementById('testme').innerText = error.message;
      console.log('Problem ', error.message);
    );
  

myTask.service.ts

  onTest() 
    return this.http.get('https://www.google.com').pipe(
      catchError(err => 
        return throwError(err);
      )
    );
  

起初我尝试了服务器的 URL,但我将其更改为“https://www.google.com”只是为了验证后端是否正确。

我还有一个interceptors.ts 文件,我用它来进行身份验证,但是当我执行onStartTest() 函数时我没有登录,但我会分享它。

interceptors.ts

import Injectable from '@angular/core';
import HttpEvent, HttpHandler, HttpInterceptor, HttpRequest from '@angular/common/http';
import Observable from 'rxjs';

@Injectable()
export class TokenInterceptor implements HttpInterceptor 


  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    const token = localStorage.getItem('auth_token');
    let newHeaders = req.headers;

    if (token) 
      console.log(token);
      newHeaders = newHeaders.set('Authorization', 'Token ' + token);
      const modified = req.clone(
        headers: newHeaders
      );
      return next.handle(modified);
     else 
      newHeaders = newHeaders.set('Content-Type', 'application/json');
      const modified = req.clone(
        headers: newHeaders
      );
      return next.handle(modified);
    
  

我认为这些是解决此问题的必要文件。 我还用 Postman 测试了 google 的 url,以确保我应该获得状态 200

我还知道当响应代码为 20x 或 30x 时,有一个“add_header”指令 (nginx) 添加“Allow-access-control-origin”。根据我与 Postman 的屏幕截图,谷歌以 200 状态响应,但我的应用程序仍然出现状态 0 错误。

忽略第一个错误。这是我在应用程序启动时与 http 一起使用的功能。现在我正在测试 https。

我表面上尝试使用 ionic-native 库 HTTP,但我的应用程序完全崩溃了。

我也执行了命令ionic serve --ssl,但还是没有。

我在某处读到,为了安全连接,我需要一个证书,但我知道这是服务器的工作。

我尝试从 Vanilla javascript 向 Dark Sky 请求,它工作正常。所以角度/离子端有问题,而不是服务器端。

我错过了什么?我真的需要尽快解决这个问题! 我想向 https url 发送安全请求并获得适当的响应。

【问题讨论】:

Google 不响应我所说的 CORS 请求 我想到了这一点,这就是我使用 Postman 测试它的原因。使用邮递员获得 200 状态。无论如何,我会尝试使用另一个 URL,但我认为这不是问题,因为当我使用服务器中的 url 时,我遇到了完全相同的错误。 我在黑暗的天空中使用了这个网址,但仍然出现同样的错误,即 https:api.darksky.net/forecast/b66bc3384e22439cafb91f9124f7c5e0/… 因为这个api也没有实现CORS。阅读有关 CORS 的信息,并且有很多与此相关的 SO 问题。这与https无关。使用 POSTMAN 发送和 OPTIONS 请求进行检查。如果您的问题是“为什么我不能从 https 网站请求 http 内容”,那么这是出于安全原因。您的错误消息清楚地表明了这一点 【参考方案1】:

您的主要问题是您正在尝试向不安全的调用 (http) 位置(来自安全来源 (https://localhost:8100) 的http://192....../mobile/tasks))创建 API。

这在您的错误消息中明确指出,这是不允许的,并且一直是answered before

您的第二个问题是,出于测试目的,您试图从您的网站调用第 3 方 https ressource。这仅在第 3 方资源实施 CORS 时才有效,而 Google 和 api.darksky.net 并非如此。使用 Postman 发送 GET 请求是没有用的,因为 Postman 在显示响应之前不会检查 CORS 标头。如果你想使用 Postman 来检查 CORS,向这些资源发送一个 OPTIONS 请求,你会看到没有 CORS 头

【讨论】:

我知道第一个错误。但是现在我正在测试 https 函数,第二个错误。第 3 方 https 的好处,我不知道。但我仍然不完全明白我能为 CORS 做些什么。我阅读了 MDN 文章和 ionic for CORS 太多次。大多数答案都说这是服务器的问题,服务器需要添加“access-control-allow-origin”标头。我会试着看看我还能找到什么。如果我没有找到任何东西,我会回到帖子。如果我找到了,我会标记这个答案。 另外我想问一下,为什么当我使用 Vanilla JavaScript 尝试它时,我的第 3 方 api 没有出现 CORS 错误?像邮递员吗?不检查 CORS 标头? 如果您拥有API,则只能通过添加headers来解决,否则需要设置代理。使用纯 JS 也会有同样的错误。在此页面上按 f12 并将其粘贴到控制台中进行验证:fetch('https://api.darksky.net/forecast/b66bc3384e22439cafb91f9124f7c5e0/32.000,%2035.000').then(resp =&gt; console.log(resp)) 我得到“从原点 '***.com' 获取在 'api.darksky.net/forecast/b66bc3384e22439cafb91f9124f7c5e0/…' 的访问权限已被 CORS 策略阻止:请求中不存在 'Access-Control-Allow-Origin' 标头资源。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。” 没错。这就是我的观点:使用普通 vanillaJS 会出现同样的错误【参考方案2】:

所以答案在MDN - CORS

出于安全原因,浏览器会限制跨域 HTTP 请求 从脚本启动。例如,XMLHttpRequest 和 Fetch API 遵循同源政策。这意味着一个 Web 应用程序使用 这些 API 只能从同一来源请求资源 应用程序是从加载的,除非来自其他来源的响应 包括正确的 CORS 标头。

这意味着我使用的后端需要更多配置,因为我使用的是“同源”策略脚本。我认为我们有它,因为当我们尝试从浏览器的控制台获取请求时,它工作正常,但在移动设备上却不是。我们有一个自定义 CORS 配置,但我们将其更改为 django-cors-headers。由于我们切换到django-cors-headers,我可以正确地得到来自 HTTP 和 HTTPS 请求的响应。 其他答案和 cmets 对于专注于正确的方向非常有用。

【讨论】:

以上是关于如何从 https 网站获取 http 内容?的主要内容,如果未能解决你的问题,请参考以下文章

网站如何从http升级成https

如何从另一个网站通过 Id 获取元素 [关闭]

如何获取网站的HTTPS证书?

如何获取网站的HTTPS证书?

如何通过图片在 HTTPS 网站中获取 HTTP 接口数据

如何将网站升级为HTTPS协议?