关于jquery:当Postman没有时,为什么我的JavaScript会在请求的资源上出现“No’Access-Control-Allow-Origin’标头”错误?

Why does my JavaScript get a “No 'Access-Control-Allow-Origin' header is present on the requested resource” error when Postman does not?

我正试图通过连接到restfulapi内置烧瓶来使用javascript进行授权。但是,当我提出请求时,我得到以下错误:

XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

我知道API或远程资源必须设置头,但是当我通过chrome扩展邮差发出请求时,为什么它会工作?

这是请求代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$.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引用:

Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.


This is not a fix for production or when application has to be shown to the client, this is only helpful when UI and Backend development are on different servers and in production they are actually on same server. For example: While developing UI for any application if there is a need to test it locally pointing it to backend server, in that scenario this is the perfect fix. For production fix, CORS headers has to be added to the backend server to allow cross origin access.

简单的方法就是在Google Chrome中添加扩展,允许使用CORS进行访问。

(https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfmbojpeacfghkpbjhddihlkkiljbi?HL=EN美国

只要您希望不允许访问任何"访问控制允许源站"头请求,就启用此扩展。

在Windows中,将此命令粘贴到运行窗口中

1
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

这将打开一个新的chrome浏览器,允许访问任何"访问控制允许源站"头请求。


如果您可以作为回报处理JSON,那么尝试使用JSONP(注意末尾的P)在域之间进行对话:

1
2
3
4
$.ajax({
  type:"POST",
  dataType: 'jsonp',
  ...... etc ......

在此了解有关使用JSONP的更多信息:

The advent of JSONP — essentially a consensual cross-site scripting hack — has opened the door to powerful mashups of content. Many prominent sites provide JSONP services, allowing you access to their content via a predefined API.


如果您使用的是PHP,解决这个问题非常简单。只需在处理请求的PHP页面的开头添加以下脚本:

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

警告:这包含一个PHP文件的安全问题,攻击者可能会调用该文件。您必须使用会话和cookie进行身份验证,以防止您的文件/服务受到此攻击。您的服务容易受到跨站点请求伪造(CSRF)的攻击。

如果您使用的是红色节点,则必须通过取消注释以下行来允许node-red/settings.js文件中的CORS:

1
2
3
4
5
6
7
8
// 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"
},


我希望很久以前有人与我共享这个站点http://cors.io/,与构建和依赖我自己的代理相比,它可以节省大量的时间。但是,当您进入生产环境时,拥有自己的代理是最好的选择,因为您仍然可以控制数据的所有方面。

你所需要的一切:

https://cors.io/?http://HTTP_YOUR_LINK_HERE


如果您使用的是node.js,请尝试:

1
2
3
4
5
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin","*");
    res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
    next();
});

更多信息:ExpressJS上的CORS


使用Ajax存在跨域问题。您必须确保在不使用www.的情况下访问同一个http://路径上的文件(或从http://www.访问并发布到浏览器通过www.路径访问时视为另一个域的同一路径,包括www.路径,这样您就可以看到问题所在。您要发布到其他域,浏览器会因为源站问题而阻止流。

如果API没有放置在您请求的同一个主机上,那么流将被阻塞,您需要找到另一种与API通信的方法。


因为
$.Ajax(type:"post"-调用选项
$post(-calls post

两者都是不同的邮递员正确地称为"邮差",但当我们称之为"选项"

对于C Web服务-WebAPI

请在web.config文件的标记下添加以下代码。这会起作用

1
2
3
4
5
<httpProtocol>
    <customHeaders>
       
    </customHeaders>
</httpProtocol>

请确保在Ajax调用中没有出错

JQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.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");
    }
});

角度4问题请参考:http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/

注意:如果您要从第三方网站下载内容,这将不会对您有所帮助。您可以尝试以下代码,但不能尝试JavaScript。

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


试试XDomain,

Summary: A pure JavaScript CORS alternative/polyfill. No server configuration required - just add a proxy.html on the domain you wish to communicate with. This library uses XHook to hook all XHR, so XDomain should work in conjunction with any library.


如果您不想:

  • 禁用Chrome中的Web安全性
  • 使用JSONP
  • 使用第三方网站重新路由您的请求
  • 然后您确定您的服务器已经启用了CORS(这里的测试CORS:http://www.test-cors.org/)

    然后,您需要在请求中传递origin参数。此来源必须与浏览器发送的来源与请求匹配。

    您可以在这里看到它的实际作用:http://www.wikinomad.com/app/detail/campgrounds/3591

    编辑功能将get&post请求发送到其他域以获取数据。我设置了解决问题的原点参数。后端是Mediawiki引擎。

    tldr:在调用中添加"origin"参数,该参数必须是浏览器发送的origin参数(不能欺骗origin参数)。


    我在使用AngularJS访问API时遇到了这个问题。同样的请求也适用于Soapui5.0和ColdFusion。我的get方法已经有了访问控制allow origin头。

    我发现AngularJS提出了一个"试用"选项请求。默认情况下,coldfusion会生成options方法,但它没有太多的选项,具体来说就是这些头文件。该错误是为响应该选项调用而生成的,而不是为响应我的故意调用而生成的。在将下面的选项方法添加到API之后,问题就解决了。

    1
    2
    3
    4
    5
    6
    <cffunction name="optionsMethod" access="remote" output="false" returntype="any" httpmethod="OPTIONS" description="Method to respond to AngularJS trial call">
        <cfheader name="Access-Control-Allow-Headers" value="Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin">
        <cfheader name="Access-Control-Allow-Methods" value="GET,OPTIONS">      
        <cfheader name="Access-Control-Allow-Origin" value="*">      
        <cfheader name="Access-Control-Max-Age" value="360">        
    </cffunction>


    基于Shruti的回答,我创建了一个Chrome浏览器的快捷方式,其中包含了必要的参数:enter image description hereenter image description here


    https://github.com/rob--w/cors-anywhere/提供(node.js)代码,可用于设置和运行自己的CORS代理。它是主动维护的,除了基本发送正确的Access-Control-*响应头之外,还提供了许多控制代理行为的功能。

    https://developer.mozilla.org/en-us/docs/web/http/access_control_cors提供了详细说明浏览器如何处理客户端Web应用程序从javascript发出的跨源请求,以及如果可以,您必须配置由服务器发送请求的头。

    如果需要向其发出请求并从中获得响应的站点没有返回Access-Control-Allow-Origin响应头,浏览器总是会阻止客户端javascript代码直接向其发出的跨源请求工作。因此,如果站点不是您所控制的站点,并且可以为其配置行为,那么在这种情况下,唯一可以工作的就是通过您自己运行的代理或通过开放代理来代理请求。

    正如这里的其他评论中提到的,有充分的理由不将开放代理与您的请求相信任。也就是说,如果你知道自己在做什么,并且决定一个开放的代理可以满足你的需求,那么https://cors-anywhere.herokupp.com/是一个可靠的、主动维护的代理,它运行着https://github.com/rob--w/cors-anywhere/代码的实例。

    与这里提到的其他开放代理(其中至少有两个似乎不再可用)一样,它的工作方式是,不让客户机代码直接向(例如,http://foo.com)发送请求,而是将其发送到https://cors-anywhere.herokuapp.com/http://foo.com,代理将必要的Access-Control-*头添加到浏览器看到的响应中。


    通过使用YQL通过雅虎服务器代理请求,可以绕过这个问题。这只是几行代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var yql_url = 'https://query.yahooapis.com/v1/public/yql';
    var url = 'your api url';

    $.ajax({
        'url': yql_url,
        'data': {
            'q': 'SELECT * FROM json WHERE url="'+url+'"',
            'format': 'json',
            'jsonCompat': 'new',
        },
        'dataType': 'jsonp',
        'success': function(response) {
            console.log(response);
        },
    });

    这里有一个解释链接:https://vverma.net/fetch-any-json-using-jsonp-and-yql.html


    我进行了以下配置,在从服务器请求响应时导致了相同的错误。

    服务器端:sparkjava->提供rest-api客户端:extjs6->提供浏览器渲染

    在服务器端,我必须将此添加到响应中:

    1
    2
    3
    4
    Spark.get("/someRestCallToSpark", (req, res) -> {
        res.header("Access-Control-Allow-Origin","*"); //important, otherwise its not working
        return"some text";
     });

    在客户端,我必须将此添加到请求中:

    1
    2
    3
    4
    5
    6
    Ext.Ajax.request({
        url:"http://localhost:4567/someRestCallToSpark",
        useDefaultXhrHeader: false, //important, otherwise its not working
        success: function(response, opts) {console.log("success")},
        failure: function(response, opts) {console.log("failure")}
    });


    如果您使用的是实体框架,那么即使启用了CORS,有时也会抛出此错误。我发现这个错误是由于查询的未完成而导致的。我希望这能在同样的情况下帮助其他人。

    以下代码可能引发XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.错误:

    1
    2
    3
    4
    5
    6
    7
    8
    using (DBContext db = new DBContext())
    {
        return db.Customers.Select(x => new
        {
            Name = x.Name,
            CustomerId = x.CustomerId,
        });
    }

    要解决此问题,需要在查询结束时进行诸如.ToList().FirstOrDefault()之类的定案调用,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    using (DBContext db = new DBContext())
    {
        return db.Customers.Select(x => new
        {
            Name = x.Name,
            CustomerId = x.CustomerId,
        }).ToList();
    }


    在我的案例中,我使用的是Jee7JAX-RS应用程序,以下技巧对我来说非常有效:

    1
    2
    3
    4
    5
    6
    7
    @GET
        @Path("{id}")
        public Response getEventData(@PathParam("id") String id) throws FileNotFoundException {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/eventdata/" + id +".json");
            JsonReader jsonReader = Json.createReader(inputStream);
            return Response.ok(jsonReader.readObject()).header("Access-Control-Allow-Origin","*").build();
        }

    我成功地使用htaccess解决了(在字体方面),但很明显,op要求的差别不大。但是您可以使用filematch模式并添加任何类型的扩展,这样就不会出现cros错误。

    1
    2
    3
    4
    5
    <IfModule mod_headers.c>
      <FilesMatch"\.(ttf|ttc|otf|eot|woff|woff2|font.css|css)$">
        Header set Access-Control-Allow-Origin"*"
      </FilesMatch>
    </IfModule>

    https://httpd.apache.org/docs/2.4/mod/core.html文件匹配


    流行的问题——如果你已经读了这么多,而且没有其他帮助的话,另一件事要看。如果您有一个cdn(如Akamai、Limelight或类似产品),您可能需要检查您拥有的缓存密钥,以获取资源的URI。如果它不包含原始头值,则当从其他源请求时,您可能返回缓存的响应。我们花了半天时间调试这个。cdn配置被更新为仅包含我们的一些选定域的源值,并将所有其他域的源值设置为空。这似乎有效,允许来自已知域的浏览器查看我们的资源。当然,所有其他的答案都是到达这里的先决条件,但是如果cdn是您的浏览器的第一个跃点,那么这是需要检查的。

    在我们的案例中,我们可以看到一些请求向我们的服务发出,但并没有接近站点发送的卷。这就指向了cdn。我们能够返回并看到原始请求是直接请求提供的,而不是浏览器Ajax调用的一部分,并且响应头访问控制allow origin不包括在内。显然,cdn缓存了这个值。将源站请求头值作为匹配的一部分考虑在内的Akamai cdn配置调整似乎使其对我们有用。


    对于Golang API:

    首先,您可以查看MDN CORS文档,了解什么是CORS。据我所知,CORS是关于是否允许请求的来源访问服务器资源。

    通过在服务器响应的Header处设置Access-Control-Allow-Origin来限制哪个请求来源可以访问服务器。

    例如,在服务器响应中设置以下头意味着只有从http://foo.example发送的请求才能访问您的服务器:

    1
    Access-Control-Allow-Origin: http://foo.example

    以及以下允许来自任何来源(或域)的请求:

    1
    Access-Control-Allow-Origin: *

    正如我在错误消息中所知道的,requested resource表示服务器的资源,所以No 'Access-Control-Allow-Origin' header is present on the requested resource.表示服务器响应中没有设置Access-Control-Allow-Origin头,或者您设置了,但请求的来源在Access-Control-Allow-Origin中没有列出,所以请求是不允许访问的:

    No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

    在Golang中,我使用gorilla/mux包在localhost:9091上构建API服务器,我允许cors通过向响应头添加"Access-Control-Allow-Origin","*"来实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    func main() { // API Server Code
        router := mux.NewRouter()
        // API route is /people,
        //Methods("GET","OPTIONS") means it support GET, OPTIONS
        router.HandleFunc("/people", GetPeople).Methods("GET","OPTIONS")
        log.Fatal(http.ListenAndServe(":9091", router))
    }

    // Method of '/people' route
    func GetPeople(w http.ResponseWriter, r *http.Request) {

        // Allow CORS by setting * in sever response
        w.Header().Set("Access-Control-Allow-Origin","*")

        w.Header().Set("Access-Control-Allow-Headers","Content-Type")
        json.NewEncoder(w).Encode("OKOK")
    }

    我在客户端使用了javascript,在localhost:9092上,通过chrome发出请求可以成功地从服务器localhost:9091获得"okok"。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function GetPeople() {
        try {
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET","http://localhost:9091/people", false);
            xhttp.setRequestHeader("Content-type","text/html");
            xhttp.send();
            var response = JSON.parse(xhttp.response);
            alert(xhttp.response);
        }
        catch (error) {
            alert(error.message);
        }
    }

    此外,您还可以使用诸如Fiddler之类的工具检查请求/响应头。


    如果从浏览器收到此错误消息:

    1
    No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access

    当您试图对您无法控制的远程服务器执行Ajax post/get请求时,请忽略此简单修复:

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

    您确实需要,特别是如果您只使用JavaScript来执行Ajax请求,那么需要一个内部代理,它接收您的查询并将其发送到远程服务器。

    首先,在JavaScript代码中,对您自己的服务器执行Ajax调用,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $.ajax({
        url: yourserver.com/controller/proxy.php,
        async: false,
        type:"POST",
        dataType:"json",
        data: data,
        success: function (result) {
            JSON.parse(result);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.log(xhr);
        }
    });

    然后,创建一个名为proxy.php的简单php文件来包装日志数据,并将其作为参数附加到远程URL服务器。我给您举一个示例,说明如何使用Expedia Hotel Search API绕过此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (isset($_POST)) {
      $apiKey = $_POST['apiKey'];
      $cid = $_POST['cid'];
      $minorRev = 99;

      $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

      echo json_encode(file_get_contents($url));
     }

    通过做:

    1
    echo json_encode(file_get_contents($url));

    您只是在执行相同的查询,但是在服务器端,在这之后,它应该可以正常工作。

    从nizarbb复制粘贴的答案


    很多时候,从javascript到php api,这都发生在我身上,因为其中一个原因。我忘了说江户一〔4〕就是其中之一。这有助于跨子域访问。另一个原因是,在jquery ajax请求中,我指定了一个特定的数据类型并返回了一个不同的数据类型,所以它抛出了一个错误。

    这个错误的最后一个也是最突出的原因是在您请求的页面上有一个解析错误。如果您在浏览器中点击了该页面的URL,那么您很可能会看到一个解析错误,并且您将有一个行号来解决这个问题。

    我希望这能帮助别人。每次调试都花了我一段时间,我希望我有一个检查清单来验证。


    如果您想在后端(在flask中)而不是前端修复这个问题,我完全推荐flask-cors-python包。烧瓶科斯

    只需在app.py中插入一行,您就可以自动插入标准的"允许任何原点"标题,或者根据需要进行自定义。


    为了完整性,Apache允许CORS:

    1
    2
    3
    4
    Header set Access-Control-Allow-Origin"http://www.allowonlyfromthisurl.com"
    Header set Access-Control-Allow-Methods"POST, GET, OPTIONS, DELETE, PUT"
    Header set Access-Control-Max-Age"1000"
    Header set Access-Control-Allow-Headers"x-requested-with, Content-Type, Accept-Encoding, Accept-Language, Cookie, Referer"


    在jsonp请求中,您应该捕获"jsonpcallback"并将其发送回去。

    1
    2
    3
    4
    5
    6
    7
    8
    $.ajax({
          url: lnk,
          type: 'GET',
          crossDomain: true,
          dataType: 'jsonp',
          success: function (ip) { console.log(ip.ip); },
          error: function (err) { console.log(err) }
    });

    在后端(如果用作后端PHP)

    1
    echo $_GET['callback'].'({"ip":"192.168.1.1"})';

    在这种情况下,后端响应看起来像

    jQuery331009526199802841284_1533646326884({"ip":"192.168.1.1"})

    但您可以在前端手动设置"jsonpcallback",并在后端捕获他。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $.ajax({
          url: lnk,
          type: 'GET',
          crossDomain: true,
          dataType: 'jsonp',
          jsonpCallback: 'get_ip',
          success: function (ip) { console.log(ip.ip); },
          error: function (err) { console.log(err) }
    });

    在这种情况下,后端响应看起来像

    get_ip({"ip":"192.168.1.1"})


    这些答案中的大多数告诉用户如何将CORS头添加到他们控制的服务器上。

    但是,如果您需要来自不在网页中控制的服务器的数据,一种解决方案是在网页上创建脚本标记,将src属性设置为没有CORS头的API端点,然后将该数据加载到网页上:

    1
    2
    3
    4
    5
    6
    7
    window.handleData = function(data) {
      console.log(data)
    };

    var script = document.createElement('script');
    script.setAttribute('src','https://some.api/without/cors/headers.com&callback=handleData');
    document.body.appendChild(script);


    CORS是为你准备的。

    CORS是"跨源资源共享",是一种发送跨域请求的方式。现在XMLHttpRequest2和Fetch API都支持CORS。

    但它有其局限性。服务器需要指定声明访问控制允许源站,并且不能将其设置为"*"。

    如果您希望任何来源可以向您发送请求,则需要jsonp(还需要设置访问控制允许来源,但可以是"*"。

    对于很多请求方式,如果您不知道要选择什么,我认为您需要一个完全功能化的组件来完成这项工作。让我介绍一个简单的组件catta

    如果您使用的是现代浏览器(>Internet Explorer9、Chrome、Firefox、Edge等),建议您使用一个简单但漂亮的组件,https://github.com/joker-jelly/catta。它没有依赖关系,小于3kb,并且支持fetch、ajax和jsonp,具有相同的死简单语法和选项。

    1
    2
    3
    catta('./data/simple.json').then(function (res) {
      console.log(res);
    });

    它还支持导入到您的项目中的所有方法,比如ES6模块、CommonJS甚至HTML中的


    在我的网站(基于.NET)上,我刚刚添加了:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <system.webServer>
     <httpProtocol>  
        <customHeaders>  
           
           
           
        </customHeaders>  
      </httpProtocol>        
    </system.webServer>

    非常感谢这段视频。


    我在角度上得到了这个错误。我需要用$http.jsonp来代替。


    对于application_controller.rb中的RubyonRails服务器,添加以下内容:

    1
    2
    3
    4
    5
    6
    7
    after_action :cors_set_access_control_headers

    def cors_set_access_control_headers
      headers['Access-Control-Allow-Origin'] = '*'
      headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
      headers['Access-Control-Allow-Headers'] = '*'
    end


    这个解决方案肯定对你有用。添加自定义消息句柄

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class CustomHeaderHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request, CancellationToken cancellationToken)
        {
            HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
            var referrer = request.Headers.Referrer;
            if (referrer != null && !response.Headers.Contains("Access-Control-Allow-Origin"))
            {
                response.Headers.Add("Access-Control-Allow-Origin", referrer.Scheme +"://" + referrer.Authority);
            }
            return response;
        }
    }

    在webapiconfig.cs中注册。

    config.messagehandlers.add(new customHeaderhandler());

    如果您使用的是信号器,那么将此代码添加到globale.asax.cs文件中。

    1
    2
    3
    4
    5
    6
    7
    8
    protected void Application_BeginRequest(object sender, EventArgs e)
            {
                var referrer = Request.UrlReferrer;
                if (Context.Request.Path.Contains("signalr/") && referrer != null)
                {
                    Context.Response.AppendHeader("Access-Control-Allow-Origin", referrer.Scheme +"://" + referrer.Authority);
                }
            }

    请求的资源上不存在"访问控制允许来源"头。因此,不允许访问源站"https://sx.xyz.com"。

    在Ajax响应中,由于错误未定义,我还遇到了类似的跨域数据交换问题。但是头中的响应是状态代码:200 OK

    1
    2
    3
    Failed to load https://www.Domain.in/index.php?route=api/synchronization/checkapikey:
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    Origin 'https://sx.xyz.in' is therefore not allowed access.

    解决方法:在我的例子中,它通过Ajax调用函数checkapikey()到另一个域,并获取对调用位置的数据响应:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->server['HTTP_ORIGIN'])) {

            $this->response->addHeader('Access-Control-Allow-Origin: ' . $this->request->server['HTTP_ORIGIN']);
            $this->response->addHeader('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
            $this->response->addHeader('Access-Control-Max-Age: 1000');
            $this->response->addHeader('Access-Control-Allow-Credentials: true');
            $this->response->addHeader('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

            $headers = getallheaders();
    ...
    }

    也许有点复杂,但您可以使用Web服务器来路由请求。有了点头,你就没有这个问题了。我不是节点JS的专家。所以我不知道这是不是干净的代码。

    但这对我有用

    这里有一点特别之处:

    节点JS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var rp = require('request-promise');
    var express = require('express'),
        app = express(),
        port = process.env.PORT || 3000;
    var options = {
        method: 'POST',
        uri: 'http://api.posttestserver.com/post',
        body: {
            some: 'payload'
        },
        json: true // Automatically stringifies the body to JSON
    };
    app.get('/', function (req, res) {
            rp(options)
            .then(function (parsedBody) {
                res.send(parsedBody)
            })
            .catch(function (err) {
                res.send(err)
            });
    });
    app.listen(port);

    JS

    1
    2
    3
    4
    5
    axios.get("http://localhost:3000/").then((res)=>{
        console.log('================res====================');
        console.log(res);
        console.log('====================================');
    })

    只需提到另一种"绕过"IT的方法——Ajax代理。向您的服务器发送请求,以从另一个来源获取数据并将请求发送回您。

    比起JSONP,我更喜欢这种方法,因为它有一些潜在的安全问题。


    对于Opera(它的工作方式与Chrome相同),我使用以下命令启动了浏览器:

    1
    opera --user-data-dir="~/Downloads/opera-session" --disable-web-security

    问题解决了!现在我可以处理本地HTML文件(在硬盘上),并在同一个文件中调用Ajax请求到远程来源。

    注1:您可以将主目录中的任何文件夹指定为--user data dir。

    注2:在Debian 8(Jessie)/Opera 39上测试

    Here is a screenshot

    当您正常启动(没有上述参数)时,相同的请求将进入错误代码块。


    我通过为访问Web API的客户机URL启用CORS解决了这个问题,并且它成功地工作了。

    例如:

    1
    [EnableCors(origins:"http://clientaccessingapi.com", headers:"*", methods:"*")]

    我在自己的域中创建了一个简单的桥,它从外部域获取并显示内容。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    header("Content-Type: text/plain");
    if (isset($_GET["cnic"]))
    {
        $page = file_get_contents("https://external.domain.com/api/verify/" . $_GET["cnic"]);
        echo $page;
    }
    else
    {
        echo"";
    }

    ?>

    现在,我不再访问Ajax中的外部域,而是放置了这个桥接文件的URL。

    您应该根据需要调整Content-Type。如果数据在json中,则使用header("Content-Type: application/json");


    在我使用SpringBoot作为服务的情况下,您可以在负责的操作上添加use-cross-origin注释。

    1
    2
    3
    4
    5
    @CrossOrigin(origins ="http://localhost:4200")
    @RequestMapping(value ="getFoo", method = RequestMethod.GET)
    public ResponseEntity getFoo(){
        // do something
    }

    也许您可以将资源从生产服务器复制到开发中服务器,并具有资源的URL以进行动态调整。这样,您就可以始终从同一个原点读取数据,从而消除了跨原点异常。


    您可能不想使用JSONP,因为它有一些限制,例如不支持post方法。

    您只需要在服务器上启用CORS。

    如果您使用Spring Boot,请阅读以下文章:https://spring.io/guides/gs/rest-service-cors/

    简而言之,只要说:

    1
    @CrossOrigin(origins ="*")

    在@requestmapping注释之前。


    请在Ajax函数中添加dataType: 'jsonp',它就可以工作了。(:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        $.ajax({
          type:"POST",
          dataType: 'jsonp',
          success: function(response) {
            alert("success");
          },
          error: function(response) {
            console.log(JSON.stringify(response));
          }
        });


    我尝试了以下解决方案。只有当服务器在本地运行时,此方法才有效。

  • 在文件web.xml中放下一行。

    1
    2
    3
    4
    5
    6
    7
    8
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  • 下载cors-filter-2.1.2和java-property-utils-1.9.1并放入库中
  • 打开浏览器以允许终端(Mac)中具有以下代码的访问控制

    1
    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files