为什么我的JavaScript代码收到“所请求的资源上没有’Access-Control-Allow-Origin’标头”错误,而Postman没有?

2020/09/14 14:01 · javascript ·  · 0评论

注释:这个问题是关于为什么Postman不受XMLHttpRequest相同的CORS限制的。该问题与如何解决“无'Access-Control-Allow-Origin'...”错误无关

请停止发布


我正在尝试通过连接到内置RESTful API Flask使用JavaScript进行授权但是,当我发出请求时,出现以下错误:

XMLHttpRequest无法加载http:// myApiUrl / login所请求的资源上没有“ Access-Control-Allow-Origin”标头。因此,不允许访问原始“空”。

我知道API或远程资源必须设置标头,但是当我通过Chrome扩展程序Postman发出请求时,为什么它可以工作

这是请求代码:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });

如果我理解正确,那么您正在向页面所在的其他域执行XMLHttpRequest因此,出于安全原因,浏览器将其阻止,因为它通常允许来自相同来源的请求。当您想进行跨域请求时,需要做一些不同的事情。有关如何实现此目标的教程是使用CORS

使用邮递员时,它们不受此政策的限制。引用自跨域XMLHttpRequest

常规网页可以使用XMLHttpRequest对象从远程服务器发送和接收数据,但是它们受同一原始策略的限制。扩展不受限制。扩展可以在其起源之外与远程服务器通信,只要它首先请求跨域许可。

警告:使用Access-Control-Allow-Origin: *会使您的API /网站容易受到跨站点请求伪造(CSRF)攻击。在使用此代码之前,请确保您了解风险

如果您使用的是PHP,则非常简单只需在处理请求的PHP页面的开头添加以下脚本:

<?php header('Access-Control-Allow-Origin: *'); ?>

如果您正在使用节点红色的,你必须让CORSnode-red/settings.js被取消注释以下行文件:

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 origin: "*",
 methods: "GET,PUT,POST,DELETE"
},

如果您使用Flask与问题相同;您必须先安装flask-cors

$ pip install -U flask-cors

然后在您的应用程序中包含Flas cors。

from flask_cors import CORS

一个简单的应用程序将如下所示:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

有关更多详细信息,您可以查看Flask文档

因为
$ .ajax({type:“ POST” -调用选项
$ .post( -调用POST

两者是不同的。邮递员正确地称呼“ POST”,但是当我们称呼它为“ OPTIONS”时。

对于C#Web服务-Web API

在<system.webServer>标记下web.config文件中添加以下代码这将起作用:

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

请确保您在Ajax调用中没有做任何错误

jQuery的

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);
    },
    error: function () {
        console.log("error");
    }
});

注意:如果您要从第三方网站下载内容那么这将无济于事您可以尝试以下代码,但不能尝试JavaScript。

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");

在下面的API调查中,我使用了http://example.com而不是您的问题中http:// myApiUrl / login,因为这是第一个有效的方法。

我假设您的网页位于http://my-site.local:8088上

您看到不同结果的原因是邮递员:

  • 设置标头Host=example.com(您的API)
  • 未设置标题 Origin

当站点和API具有相同的域时,这类似于浏览器发送请求的方式(浏览器还设置了标头项目Referer=http://my-site.local:8088,但是我在Postman中看不到它)。如果设置Origin标头,通常服务器默认情况下会允许此类请求。

在此处输入图片说明

这是Postman发送请求的标准方式。但是,当您的站点和API具有不同的域时浏览器发送的请求会有所不同,然后发生CORS,浏览器会自动:

  • 设置标头Host=example.com(您以API的形式)
  • 设置标题Origin=http://my-site.local:8088(您的网站)

(标头Referer的值与相同Origin)。现在,在Chrome的“ 控制台和网络”标签中,您将看到:

在此处输入图片说明

在此处输入图片说明

当拥有Host != OriginCORS时,并且服务器检测到此类请求时,通常默认情况下阻止它

Origin=null当您从本地目录打开HTML内容时设置,并发送请求。同样的情况是,您在内发送请求<iframe>(如下面的代码片段所示(但此处Host根本未设置标头))-通常,在HTML规范说不透明来源的任何地方,都可以将其转换为Origin=null有关此的更多信息,请参见此处

fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab

如果您不使用简单的CORS请求,通常浏览器会在发送主要请求之前自动发送一个OPTIONS请求-更多信息在此处下面的代码片段显示了它:

fetch('http://example.com/api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)

您可以更改服务器的配置以允许CORS请求。

这是一个在nginx(nginx.conf文件)打开CORS的示例配置-请谨慎设置always/"$http_origin"nginx和"*"Apache-这将阻止来自任何域的CORS。

这是一个在Apache上打开CORS的示例配置(.htaccess文件)

施加CORS限制是由服务器定义并由浏览器实现的安全功能

浏览器查看服务器的CORS策略并遵守该策略。

但是,邮递员工具不会打扰服务器的CORS策略。

这就是为什么CORS错误出现在浏览器中,而不出现在Postman中的原因。

在不同的用例中遇到相同的错误。

用例:在Chrome中,当尝试以角度调用Spring REST端点时。

在此处输入图片说明

解决方案:在相应的Controller类的顶部添加@CrossOrigin(“ *”)批注。

在此处输入图片说明

如果您在使用javascript中的获取API或XMLHttpRequest获取内容时要绕过该限制,则可以使用代理服务器,以便将标头设置Access-Control-Allow-Origin*

const express = require('express');
const request = require('request');

const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.get('/fetch', (req, res) => {
  request(
    { url: req.query.url },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).send('error');
      }
      res.send(body);
    }
  )
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

上面是一个示例代码(需要节点Js),可以充当代理服务器。例如:如果我想https://www.google.com正常获取CORS错误,但是现在由于请求是通过本地托管在端口3000上的代理服务器发送的,因此代理服务器将Access-Control-Allow-Origin标头添加到响应中,不会有任何问题。

将GET请求发送到http:// localhost:3000 / fetch?url = Your URL here,而不是直接将请求发送到您要获取的URl。

Your URL here 代表您希望获取的URL,例如: https://www.google.com

仅对于.NET Core Web API项目,添加以下更改:

  1. 在Startup.cs文件services.AddMvc()ConfigureServices()方法中的之后添加以下代码
services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
            });
  1. 在Startup.cs文件app.UseMvc()Configure()方法的后添加以下代码
app.UseCors(options => options.AllowAnyOrigin());
  1. 打开要在域外部访问的控制器,并在控制器级别添加以下属性:
[EnableCors("AllowOrigin")]

如果您使用.NET作为中间层,请清楚检查route属性,例如,

我有这样的问题

[Route("something/{somethingLong: long}")] //Space.

通过此修复,

[Route("something/{somethingLong:long}")] //No space
本文地址:http://javascript.askforanswer.com/weishenmewodejavascriptdaimashoudaosuoqingqiudeziyuanshangmeiyouaccess-control-allow-originbiao.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!