我一直在努力解决这个问题已经有一段时间了,除了决定我热情地讨厌CORS之外,我还可以确认互联网上充满了各种想法,但很少有人能够解决这个问题,所以我想会试着一劳永逸地得到答案。
目标是编写可以执行以下操作的角度代码。 1.设置标头以允许CORS。 2.登录到启用CORS的应用程序(在本例中为media wiki) 3.进行api调用以接收一些JSON数据。
我甚至会设置一个测试mediawiki服务器(使用语义媒体wiki)并为此设置一个测试用户。谁知道,如果人们对此感兴趣,我甚至会尝试使用答案为Angular编写世界上最简单的CORS模块。
在服务器上我会做三件事。 安装mediawiki和语义媒体wiki 更改设置(在LocalSettings.php中)
$wgEnableAPI = true;
$wgCrossSiteAJAXdomains = array( 'http://127.0.0.1:30004' );
$wgAPIRequestLog = "$IP/log/wgAPIRequestLog.log";
并更改.htaccess以设置标题。
# CORS Headers (add this)
<ifModule mod_headers.c>
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "X-Requested-With, content-type"
</ifModule>
# BEGIN WordPress (you should have this in your original WP .htaccess)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# CORS OPTIONS (add this too)
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
我认为这就是我需要做的所有事情,因为我只能在使用chome扩展来转换原始标题后才能以角度形式发出CORS请求,我不知道这是否会起作用。
同时,如果有人对此有任何想法或好资源。请发帖。
======================现在设置=====================
现在为此目的设置了一个mediawiki
Mediawiki网址'http://v-ghost.port0.org:8081/apiwiki'
用户'whowillhelp'
密码'InternetWill'
如果您想尝试API调用: http://v-ghost.port0.org:8081/apiwiki/api.php?action=ask&query=[[Msgtype::1]]|%3FMenuName&format=jsonfm
如果您尚未登录,则会返回:
{
"error": {
"code": "readapidenied",
"info": "You need read permission to use this module",
"*": "See http://v-ghost.port0.org:8081/apiwiki/api.php for API usage"
}
}
多数好吧。 如果你以角度运行相同的http.get('http://v-ghost.port0.org:8081/apiwiki/api.php?action=ask&query=[[Msgtype::1]]|%3FMenuName&format=json',你会得到一个
XMLHttpRequest cannot load http://v-ghost.port0.org:8081/apiwiki/api.php?action=ask&query=[[MsgType::1]][[Parent::Support%20Functions]]|%3FMenuName&format=jsonfm. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:30004' is therefore not allowed access.
答案 0 :(得分:0)
谢谢Quentin。
经过大量的讨论之后,事实证明CORS完全由服务器控制,而Web服务器则不是应用程序。
所需的一切(一旦API开启)就是将内容添加到.htaccess文件中。配置Apache以读取它(http.conf)。 您还需要确保加载mod_headers(在httpd -t -D DUMP_MODULES时称为headers_module),但它应该是Apache 2的默认值。
如果有疑问,有一个测试服务:) http://client.cors-api.appspot.com/
=================似乎现在正在工作===================
当我试图成为一个善良的人回馈。这是我写的工厂。从技术上讲,如果您只想运行查询,则需要三次调用(如果需要登录)。希望它可以帮助某人
我们可能值得一提,Mediawiki(可能还有所有CORS实现)要求您登录两次,一次用于身份验证,一次使用之前发送的令牌。猜测这与构建cookie有关。
.factory('CORSconnectFactory', function($http, $q){
//To call any of the http calls just do
// CORSconnectFactory.login(options )
// .then(function(data)
var CORSconnectFactory = {};
var CORScredentials = {};
var urlInit;
var deferred = $q.defer();
var datareq = {
method: 'POST',
//url: 'http://v-ghost.port0.org:8081/dbfswiki/api.php?action=login&format=json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' //Set the coding, otherwise the server can't read you're request
}
//withCredentials: true,
/*
If you set Credentials your server gets rather picky oc CORS, more specifically Header always set Access-Control-Allow-Origin: needs to be set to exact address.
*/
//data: "lgname=APIread&lgpassword=apiread01"
}
CORSconnectFactory.initSettings = function(url, withCredentials) {
urlInit = url;
datareq.withCredentials= withCredentials;
}
CORSconnectFactory.login = function(id, password){
datareq.url = urlInit + "?action=login&format=json";
datareq.data= "lgname=" + id + "&lgpassword=" + password;
return $http(datareq)//You don't have to return this request, but it helps as it lets you use .login's promise in your code
.success(function(data) {
var results = data.login; //You might have to work around to find the right part of the structure
if ( results.result === "NoName"){
console.log("New request for Token")
} else if ( results.result === "NeedToken" ) {
console.log("Need a token this time") //Mediawiki API requires login then login with token to accept the connection.
CORScredentials = data.login
return results.result;
}
});
}
CORSconnectFactory.tokenReq = function(){
datareq.data = datareq.data = datareq.data + "&lgtoken=" + CORScredentials.token;
return $http(datareq)
.success(function (data) {
results= data.login;
CORScredentials=data.login;
console.log("And I am now " + results.result);
})
}
CORSconnectFactory.query = function(queryString) {
datareq.url = urlInit + "?action=ask&query="+ queryString + "&format=json";
datareq.data = ""; //Don't send data, it confuses the poor query (and your login details is in the token
return $http(datareq)
.success(function(data) {
var results = data.query.results;
return results;
});
}
return CORSconnectFactory;
});
答案 1 :(得分:0)
在许多层面上出现了错误:
Access-Control-Allow-Credentials
标头(如果它是公共API,只需使用JSONP)。正确配置后,MediaWiki会为您执行此操作。$wgCrossSiteAJAXdomains
将域名作为其参数,而不是URL前缀,因此应为$wgCrossSiteAJAXdomains = array( '127.0.0.1:30004' );
。origin
参数,即。正确的网址为'http://v-ghost.port0.org:8081/apiwiki/api.php?action=ask&query=[[Msgtype::1]]|%3FMenuName&format=json&origin=http://127.0.0.1:30004
。