Javascript 发出卖出请求会导致在卖出之前先发送选项请求,为什么浏览器会这样做?

Javascript 发出卖出请求会导致在卖出之前先发送选项请求,为什么浏览器会这样做?,javascript,http,cors,http-put,Javascript,Http,Cors,Http Put,当我发送一个POST请求时,它是可以的。但是,当我发送一个PUT请求(将$http.post()替换为$http.PUT())并发送一个不带数据的选项请求时,请等待响应并发送一个带数据的PUT请求 这不是问题,因为是客户端发送了2个请求 对于OPTIONS请求,不会解析JSON响应,因为Angular不会转到success函数 我不想发送选项请求。 你知道这个问题吗?你知道怎么解决吗 守则: var app = angular.module('myApp', []); app.config(fu

当我发送一个POST请求时,它是可以的。但是,当我发送一个PUT请求(将$http.post()替换为$http.PUT())并发送一个不带数据的选项请求时,请等待响应并发送一个带数据的PUT请求

这不是问题,因为是客户端发送了2个请求

对于OPTIONS请求,不会解析JSON响应,因为Angular不会转到success函数

我不想发送选项请求。 你知道这个问题吗?你知道怎么解决吗

守则:

var app = angular.module('myApp', []);
app.config(function($httpProvider) {
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
    $httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
    $httpProvider.defaults.useXDomain = true;
    //
    var param = function(obj) {
        var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
        for(name in obj) {
            value = obj[name];
            if(value instanceof Array) {
                for(i=0; i<value.length; ++i) {
                    subValue = value[i];
                    fullSubName = name + '[' + i + ']';
                    innerObj = {};
                    innerObj[fullSubName] = subValue;
                    query += param(innerObj) + '&';
                }
            }
            else if(value instanceof Object) {
                for(subName in value) {
                    subValue = value[subName];
                    fullSubName = name + '[' + subName + ']';
                    innerObj = {};
                    innerObj[fullSubName] = subValue;
                    query += param(innerObj) + '&';
                }
            }
            else if(value !== undefined && value !== null) {
                query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
            }
        }
        return query.length ? query.substr(0, query.length - 1) : query;
    };
    // Override $http service's default transformRequest (json to application/x-www-form-urlencoded)
    $httpProvider.defaults.transformRequest = [function(data) {
        return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
    }];
});
app.controller('login', function ($scope, $http) {
    $scope.run = function() {
        var file_data = $("#file").prop("files")[0];
        var datas = {email:"email@domain.com", pass:sha1("xxxxxx")};
        $http.put("http://myapi.com/user/connect", datas
            ).success(function(data, status, headers, config) {
                console.log(data);
            }).error(function(data, status, headers, config) {

            });
        return;
    }
});
第二项请求:

General
Remote Address:127.0.0.1:80
Request URL:http://api.wezit.local/user/connect
Request Method:OPTIONS
Status Code:200 OK

Response Headers
Access-Control-Allow-Methods:POST, GET, PUT, DELETE
Access-Control-Allow-Origin:*
Cache-Control:no-cache, must-revalidate
Connection:Keep-Alive
Content-Length:170
Content-Type:application/json;
Date:Fri, 17 Jul 2015 16:31:15 GMT
Expires:Mon, 26 Jul 1997 05:00:00 GMT
Keep-Alive:timeout=5, max=100
Pragma:no-cache
Server:Apache/2.4.10 (Fedora) PHP/5.5.25
Set-Cookie:PHPSESSID=2dj440b2vr2emi5ht9ojcl8gk6; path=/
Set-Cookie:PHPSESSID=q3pg80qb43ps6tpkljlvelo0k7; path=/
X-Powered-By:PHP/5.5.25

Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:PUT
Connection:keep-alive
Host:api.wezit.local
Origin:http://test.local
Referer:http://test.local/api.php
User-Agent:Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.125 Safari/537.36
General
Remote Address:127.0.0.1:80
Request URL:http://api.wezit.local/user/connect
Request Method:PUT
Status Code:200 OK

Response Headers
Access-Control-Allow-Methods:POST, GET, PUT, DELETE
Access-Control-Allow-Origin:*
Cache-Control:no-cache, must-revalidate
Connection:Keep-Alive
Content-Length:327
Content-Type:application/json;
Date:Fri, 17 Jul 2015 16:31:15 GMT
Expires:Mon, 26 Jul 1997 05:00:00 GMT
Keep-Alive:timeout=5, max=99
Pragma:no-cache
Server:Apache/2.4.10 (Fedora) PHP/5.5.25
Set-Cookie:PHPSESSID=18jfhgq2fs1p1f1nu7ua1ap8c3; path=/
Set-Cookie:PHPSESSID=14aifglpntf8amavkipclvom67; path=/
X-Powered-By:PHP/5.5.25

Request Headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:142
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:api.wezit.local
Origin:http://test.local
Referer:http://test.local/api.php
User-Agent:Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.125 Safari/537.36

Form Data
email:email@domain.com
pass:ce35927f4dcb044bceda5f385823419cb0156507

当您启动跨源请求时,浏览器总是使用选项方法发出飞行前请求。这意味着您尝试访问的API与您的应用程序位于不同的源上。你对此无能为力

你知道这个问题吗

你观察到的没有问题,这是预期的行为

当我发送一个POST请求时,它是可以的

:

特别是,如果:

  • 它使用GET、HEAD或POST以外的方法。此外,如果POST用于发送内容类型不是的请求数据 application/x-www-form-urlencoded、多部分/表单数据或text/plain, e、 g.如果POST请求使用 application/xml或text/xml,则请求将被预引导。
  • 它在请求中设置自定义头(例如,请求使用诸如X-PINGOTHER之类的头)

当您启动跨源请求时,浏览器总是使用选项方法发出飞行前请求。这意味着您尝试访问的API与您的应用程序位于不同的源上。你对此无能为力

你知道这个问题吗

你观察到的没有问题,这是预期的行为

当我发送一个POST请求时,它是可以的

:

特别是,如果:

  • 它使用GET、HEAD或POST以外的方法。此外,如果POST用于发送内容类型不是的请求数据 application/x-www-form-urlencoded、多部分/表单数据或text/plain, e、 g.如果POST请求使用 application/xml或text/xml,则请求将被预引导。
  • 它在请求中设置自定义头(例如,请求使用诸如X-PINGOTHER之类的头)

当url跨域时,飞行前选项请求的是浏览器,而不是角度。我相信这是CORS的问题。源url是
http://test.local
请求url为
http://api.wezit.local/user/connect
,因此很明显,这是一个跨域请求,我同意charlietfl。。第一次发出跨域请求时,如果浏览器没有缓存先前选项响应的副本,它将发出飞行前请求。查看此MDN以了解有关飞行前请求的更多信息。当url跨域时,浏览器不是执行飞行前选项请求的。我相信这是COR的问题。源url是
http://test.local
请求url为
http://api.wezit.local/user/connect
,因此很明显,这是一个跨域请求,我同意charlietfl。。第一次发出跨域请求时,如果浏览器没有缓存先前选项响应的副本,它将发出该飞行前请求。有关飞行前请求的更多信息,请查看此MDN。谢谢大家的响应。我并没有真正解决问题,你让我走对了路。导航器第一次发出一个选项请求,但是我的API头对于这个请求是错误的。API为所有请求禁用缓存。我修改了选项请求的标题以启用缓存一个月,导航器只对n个PUT请求发出一个请求。我是这个网站的新手,我可以将帖子标记为已解决吗?是的,你可以。如果上面的答案帮助您找到了解决方案,那么您只需选择它作为答案。这就是你们要做的。谢谢你们的回复。我并没有真正解决问题,你让我走对了路。导航器第一次发出一个选项请求,但是我的API头对于这个请求是错误的。API为所有请求禁用缓存。我修改了选项请求的标题以启用缓存一个月,导航器只对n个PUT请求发出一个请求。我是这个网站的新手,我可以将帖子标记为已解决吗?是的,你可以。如果上面的答案帮助您找到了解决方案,那么您只需选择它作为答案。这就是你要做的。