如何使用带有JQuery的书签,作为跨域请求(CORS)发送403 Authentication头?

des*_*est 2 javascript authentication jquery cors http-status-code-401

所以我有一个在其他网站上执行javascript的bookmarklet,我想在点击它上面403 Authentication RequiredCache按钮后触发一个标题.这样,会出现一个提示,要求他们登录.

苹果网站上的clickrobot

问题是,我并不打算提供带有我正在制作的ajax请求的身份验证标头,同时Access-Control-Allow-Origin:设置了具有该*值的任何域.我应该明确定义哪个域我想允许403身份验证标头出现,但我不能.

这是我的代码.

的.htaccess

header set Access-Control-Allow-Origin: *
#header set Access-Control-Allow-Methods: GET, POST, PUT, DELETE
header set Access-Control-Allow-Headers: Authorization
Run Code Online (Sandbox Code Playgroud)

JQuery的

$.ajax({
            headers : {
                "Authorization" : "Basic TVNF3TQtU1BGMjAx6C12bVxzbW4ydHBvaW50OlF3Z5J0eSEyM6Q1"
            },
            type: "GET",
            url: 'http://desbest.uk.to/clickrobot/favicon.png', //image for testing
            crossDomain:true,
            xhrFields: {
                withCredentials: true
            }, 
            //contentType: "application/json; charset=utf-8",
            //dataType: "json",
            success: function(data) {
                alert('ok!');
                //formatData(format_type,data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                alert(textStatus + ' / ' + errorThrown);
            }
        }); 
Run Code Online (Sandbox Code Playgroud)

我得到的错误

当credentials标志为true时,无法在Access-Control-Allow-Origin中使用通配符.

我已经看过Diigo bookmarklet这样做了,所以它有可能,但是怎么样?有可能吗?

den*_*isg 5

我们来看看文档.有两点需要注意:

...浏览器将拒绝任何没有Access-Control-Allow-Credentials:true标头的响应...

重要说明:在响应凭证请求时,服务器必须指定域,并且不能使用通配符.

您应该返回的标题是:

Access-Control-Allow-Origin: [some_origin]
Access-Control-Allow-Credentials: true 
Run Code Online (Sandbox Code Playgroud)

您可以通过使用服务器脚本获取Referer来返回第一个标头,从Referer检索原点,然后使用脚本返回标头.在PHP中,我们可以这样做:

$urllist = parse_url($_SERVER['HTTP_REFERER']);
$origin = $urllist['scheme'] . '://' . $urllist['host'];
header("Access-Control-Allow-Origin: " . $origin);
Run Code Online (Sandbox Code Playgroud)

更新: 您应该阅读Access-Control-Allow-Origin多个原始域,特别是这个答案.如果可以访问httpd.conf,则可能不需要PHP文件

无论如何,您的网址不应该是图片,而是您的PHP脚本的网址.

url: 'http://desbest.uk.to/clickrobot/somescript.php'
Run Code Online (Sandbox Code Playgroud)

在你的PHP脚本中,你检索请求的来源(这将是书签出现的页面.然后你可以输出带有原点的标题.无论如何,书签出现的位置,它应该总是关于正确的标题.

我不完全确定,如果授权对话框将使用Ajax弹出,即使您指定了正确的标头.所以,这就是为什么我们将在下面看看Diigo.


Diigo使用不同的方法,即:点击"登录"后,JSONP用于请求在其服务器上由服务器端脚本(例如PHP)生成的javascript文件.JSONP是CORS的替代品.与Ajax请求不同,来自不同的JavaScript文件可以包含在页面的标题中,完全没有问题.

如果用户未登录,请求javascript文件将发送401标头,其中显示Authentication对话框(这是在服务器端脚本中编码的!).用户输入他/她的详细信息并根据输入的信息返回javascript文件的内容.如果用户成功登录,则可以返回类似的内容callback({ signedin : 1}),但不然callback({ signedin : 0}).

现在调用具有某些参数的javascript函数回调.如果用户已登录,我们将显示bookmarklet的内容.


放入htaccess的内容: 未经测试,但您希望允许所有来源并将"Access-Control-Allow-Origin"标题设置为原点的值.我相信这应该可以解决问题:

SetEnvIf Origin "^(.*)$" ORIGIN_DOMAIN=$1
Header set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN
Run Code Online (Sandbox Code Playgroud)