AngularJS:在 $http.post 请求之前的 OPTIONS 预检调用

2023-04-18前端开发问题
6

本文介绍了AngularJS:在 $http.post 请求之前的 OPTIONS 预检调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在使用 AngularJS v1.2.4.

I'm using AngularJS v1.2.4.

我在 Angular 发送预检 OPTIONS 调用时遇到问题(Chrome 将 OPTIONS 调用显示为已取消")并通过以下方式解决:

I had an issue with Angular sending a preflight OPTIONS call (Chrome was showing the OPTIONS call as 'canceled') and resolved it with:

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

这对我所有的 $resource 调用都有效,一切都很好.

That worked for all my $resource calls, and everything was good.

现在我正在尝试实现身份验证,以及一个使用用户凭据向我的服务器发送 POST 请求的登录页面.我看到了我之前遇到的问题,但是 $resource 调用仍然可以正常工作.

Now I'm trying to implementation authentication, and a login page that sends a POST request to my server with the user's credentials. I'm seeing the problem I was facing before, but $resource calls are still working fine.

真正令人沮丧的是问题是间歇性发生的.我将更改标题周围的一些选项,然后它会工作一段时间,然后在不更改任何代码的情况下再次停止工作.

What's really frustrating is that the problem happens intermittently; I'll change a few options surrounding the headers, then it'll work for a bit, and stop working again without any code change.

我的服务器针对 CORS 进行了配置,并且可以与 curl 和其他 REST 客户端一起正常工作.这是一个例子:

My server is configured for CORS and works fine with curl, and other REST clients. Here's an example:

curl -X OPTIONS -ik 'https://localhost:3001/authenticate' -H "Origin: https://localhost:8001"
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
content-length: 2
cache-control: no-cache
access-control-allow-origin: *
access-control-max-age: 86400
access-control-allow-methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
access-control-allow-headers: Authorization, Content-Type, If-None-Match, Access-Control-Allow-Headers, Content-Type
access-control-expose-headers: WWW-Authenticate, Server-Authorization
set-cookie: session=Fe26.2**94705d49717d1273197ae86ce6661775627d7c6066547b757118c90c056e393b*2KYqhATojPoQhpB2OwhDwg*W9GsJjK-F-UPqIIHTBHHZx1RXipo0zvr97_LtTLMscRkKqLqr8H6WiGd2kczVwL5M25FBlB1su0JZllq2QB-9w**5510263d744a9d5dc879a89b314f6379d17a39610d70017d60acef01fa63ec10*pkC9zEOJTY_skGhb4corYRGkUNGJUr8m5O1US2YhaRE; Secure; Path=/
Date: Wed, 18 Dec 2013 23:35:56 GMT
Connection: keep-alive

这是 $http.post 调用:

Here's the $http.post call:

var authRequest = $http.post('https://' + $location.host() + ':3001/authenticate', {email: email, password: password});

当我的应用调用有效时,OPTIONS 请求如下所示:

When the call from my app works, this is how the OPTIONS request looks like:

当它不起作用时,这是 OPTIONS 请求:

When it doesn't work, this is the OPTIONS request:

看起来缺少一大堆标题属性.有没有人遇到过类似的问题?

It looks like a whole bunch of header attributes are missing. Has anyone encountered a similar issue?

澄清一下,当它不起作用时,请求永远不会到达服务器 - 它会立即在浏览器中中止.

Just to clarify, when it doesn't work, the request never makes it to the server - it's instantly aborted in the browser.

在 Firebug 中,请求标头是:

In Firebug, the request headers are:

OPTIONS /authenticate HTTP/1.1
Host: localhost:3001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.91,en-GB;q=0.82,fr-FR;q=0.73,fr;q=0.64,utf-8;q=0.55,utf;q=0.45,de-DE;q=0.36,de;q=0.27,en-sg;q=0.18,en-ca;q=0.09
Accept-Encoding: gzip, deflate
Origin: https://localhost:8001
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Proxy-Authorization: Basic cGF0cmljZUB6b25nLmNvbTpjaGFuZ2VtZQ==
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

更新:

我认为,通过将主机更改为不存在的服务器,我已经消除了服务器可能出现的问题.仍然看到相同的行为.

I've eliminated the possibly of a problem with the server, I think, by changing the host to a non-existent server. Still seeing the same behavior.

这里有一些代码:

App.services.factory('AuthService', function ($http, $location, $q) {

    var currentUser;

    return {
        authenticate: function (email, password) {

            //promise to return
            var deferred = $q.defer();

            var authRequest = $http.post('https://this.does.not.exist.com:3001/authenticate', {email: email, password: password});

            authRequest.success(function (data, status, header, config) {
                currentUser = data;
                console.log('currentUser in service set to:');
                console.log(currentUser);
                //resolve promise
                deferred.resolve();
            });

            authRequest.error(function (data, status, header, config) {
                console.log('authentication error');
                console.log(status);
                console.log(data);
                console.log(header);
                console.log(config);

                //reject promise
                deferred.reject('authentication failed..');
            });

            return deferred.promise;
        },
        isAuthenticated: function () {
            return currentUser !== undefined;
        }
    };
});

和 HTTP 配置:

App.config(['$httpProvider', function ($httpProvider) {

    $httpProvider.defaults.useXDomain = true;
    //$httpProvider.defaults.headers.common = {};

    console.log('logging out headers');
    console.log($httpProvider.defaults);
    console.log($httpProvider.defaults.headers.common);
    console.log($httpProvider.defaults.headers.post);
    console.log($httpProvider.defaults.headers.put);
    console.log($httpProvider.defaults.headers.patch);
    console.log('end logging out headers');

    $httpProvider.defaults.headers.common = {Accept: "application/json, text/plain, */*"};
    $httpProvider.defaults.headers.post = {"Content-Type": "application/json;charset=utf-8"};

    console.log('after: logging out headers');
    console.log($httpProvider.defaults.headers.common);
    console.log($httpProvider.defaults.headers.post);
    console.log($httpProvider.defaults.headers.put);
    console.log($httpProvider.defaults.headers.patch);
    console.log('after: end logging out headers');

    $httpProvider.interceptors.push(function ($location, $injector) {
        return {
            'request': function (config) {

                console.log('in request interceptor!');

                var path = $location.path();
                console.log('request: ' + path);

                //injected manually to get around circular dependency problem.
                var AuthService = $injector.get('AuthService');
                console.log(AuthService);
                console.log(config);

                if (!AuthService.isAuthenticated() && $location.path() != '/login') {
                    console.log('user is not logged in.');
                    $location.path('/login');
                }

                //add headers
                console.log(config.headers);
                return config;
            }
        };
    });
}]);

推荐答案

这感觉可能与您在本地主机上访问 https 端点有关.这意味着您可能正在使用某种自签名 SSL 证书,这可能意味着 Chrome 认为它不受信任.

This feels like it might be related to the fact that you're hitting an https endpoint on your localhost. That means you're probably using some sort of self-signed SSL certificate, which may mean Chrome considers it untrusted.

我首先尝试直接访问/authenticate 端点,看看 Chrome 是否会向您发出有关不受信任的证书的警告.看看接受该警告是否有效.

I'd first try going directly to the /authenticate endpoint and see if Chrome gives you a warning about an untrusted certificate. See if accepting that warning works.

否则,当您在本地进行测试时,您可能只需点击一个 http 端点,看看是否能解决问题?

Otherwise, possibly while you're testing locally you can hit just an http endpoint and see if that solves things?

这篇关于AngularJS:在 $http.post 请求之前的 OPTIONS 预检调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

ajax请求获取json数据并处理的实例代码
ajax请求获取json数据并处理的实例代码 $.ajax({ type: 'GET', url: 'https://localhost:44369/UserInfo/EditUserJson',//请求数据 data: json,//传递数据 //dataType:'json/text',//预计服务器返回的类型 timeout: 3000,//请求超时的时间 //回调函数传参 suc...
2024-11-22 前端开发问题
215

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5