Angular4为存在并公开服务的json数据提供404
Posted
技术标签:
【中文标题】Angular4为存在并公开服务的json数据提供404【英文标题】:Angular4 giving 404 for json data that exists and is publicly serving 【发布时间】:2017-10-31 07:27:39 【问题描述】:我有一个用 Angular4 编写的测试数据服务。目前看起来是这样的:
import Injectable from '@angular/core';
import Http from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise'
@Injectable()
export class DataService
constructor(private http: Http)
fetchData()
return this.http.get('https://dinstruct-d4b62.firebaseio.com/.json').map(
(res) => res.json()).toPromise();
感谢“The Net Ninja”提供此代码,因为该应用程序的这一部分与教程代码基本完全相同(我更喜欢在构建新应用程序时提供一些应该是已知的工作示例以用于测试目的)...
问题是,虽然https://dinstruct-d4b62.firebaseio.com/.json 肯定有测试数据,据我所知,它没有以任何方式隐藏或防火墙(可通过浏览器直接访问),但当应用程序进入fetchData()
函数时,它记录:
ERROR Error: Uncaught (in promise): Error: Response with status: 404 Not Found for URL: https://dinstruct-d4b62.firebaseio.com/.json
Error: Response with status: 404 Not Found for URL: https://dinstruct-d4b62.firebaseio.com/.json
在堆栈跟踪的开头。这里会发生什么?
更新:
我还注意到在调用函数中:
ngOnInit(): void
this.customerService.getCustomers()
.then(customers => this.customers = customers);
this.dataService.fetchData().subscribe(
(data) => console.log(data));
当我在代码中有this.dataService.fetchData().subscribe((data) => console.log(data));
时,单击指向仪表板的链接会立即在浏览器地址栏中显示localhost:3000/dashboard
,但随后会立即弹回显示先前的URL。但是,当我删除此行时,应用程序始终正确显示 localhost:3000/dashboard
。我认为这可能与 console.logged 404 错误有关。
另外令人困惑的是,当我检查网络流量时,没有显示 404。
更新:
当 observable 变为 promise 时,我会在控制台中得到以下输出:
Response _body: Object, status: 404, ok: false, statusText: "Not Found", headers: Headers…
headers
:
Headers
ok
:
false
status
:
404
statusText
:
"Not Found"
type
:
null
url
:
"https://dinstruct-d4b62.firebaseio.com/.json"
_body
:
Object
error
:
"Collection 'undefined' not found"
__proto__
:
Object
constructor
:
function Object()
hasOwnProperty
:
function hasOwnProperty()
isPrototypeOf
:
function isPrototypeOf()
propertyIsEnumerable
:
function propertyIsEnumerable()
toLocaleString
:
function toLocaleString()
toString
:
function ()
valueOf
:
function valueOf()
__defineGetter__
:
function __defineGetter__()
__defineSetter__
:
function __defineSetter__()
__lookupGetter__
:
function __lookupGetter__()
__lookupSetter__
:
function __lookupSetter__()
get __proto__
:
function __proto__()
set __proto__
:
function __proto__()
__proto__
:
Body
constructor
:
function Response(responseOptions)
toString
:
function ()
__proto__
:
Object
网络流量中仍然没有404。
我现在将调用函数更新为:
ngOnInit(): void
this.customerService.getCustomers()
.then(customers => this.customers = customers);
this.dataService.fetchData().then((data) =>
console.log(data);
)
.catch((error) => console.error(error));
【问题讨论】:
缺少型号名称? 我测试的时候效果很好,你以前没有用过内存web api吗? 我用 URL 创建了一个 plunker,它返回的数据很好。检查您是否正确导入了所有模块。 plnkr.co/edit/MMly1tMo2ZOI2cIWqnit?p=preview 没有模块错误;我猜代码和数据交换之间有些东西 没问题,很高兴我们把它解决了!即使需要一段时间:) 【参考方案1】:尝试导入import 'rxjs/add/operator/toPromise';
并将toPromise 添加到fetchData() 函数中http get 的末尾。
fetchData()
return this.http.get('https://dinstruct-d4b62.firebaseio.com/.json').map(
(res) => res.json()).toPromise();
您的调用函数应如下所示:
this.dataService.fetchData()
.then((data) =>
console.log(data);
)
.catch((error) => console.error(error));
【讨论】:
这解决了浏览器地址故障和另一个不相关的问题,但原来的问题仍然存在。 我在控制台中仍然收到 404,但在网络流量中仍然没有 404。 我刚刚尝试运行我编辑的代码,我正在控制台中接收数据。您能否编辑问题以显示您对文件所做的编辑。 发布的编辑当前显示在代码中。由于进行了建议的修改,主应用程序错误没有得到修复。 您以前的版本和我所做的更新都适用于我。我不确定是什么导致了这个错误,因为它对我和其他一些人来说非常有效。您是否尝试过重新编译应用程序?还是使用其他网络浏览器?【参考方案2】:in-memory-web-api 会干扰您的“外部”请求。你需要从你的 NgModule 中删除它,否则 Angular 总是试图在 in-memory-web-api 中查找你的请求,这显然不存在于那个地方。所以删除相当于
InMemoryWebApiModule.forRoot(InMemoryDataService)
从您的 ngModule 中清除它! :)
【讨论】:
现在得到XMLHttpRequest cannot load https://console.firebase.google.com/project/dinstruct-d4b62/database/data/.json/NaN. Redirect from 'https://console.firebase.google.com/project/dinstruct-d4b62/database/data/.json/NaN' to 'https://accounts.google.com/ServiceLogin?passive=1209600&osid=1&continue=ht…onsole.firebase.google.com/project/dinstruct-d4b62/database/data/.json/NaN' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
但是a)这不是我询问的404 b)我可以解决这个问题
这是一个CORS问题,你需要在服务器端启用cors。我对firebase不是很熟悉,所以我不能真正帮助你了解更多细节。有时虽然这只是由浏览器引起的(也是),所以您可以尝试在浏览器中启用 cors,这是 chrome 的扩展名:chrome.google.com/webstore/detail/allow-control-allow-origi/… 希望这会清除它,但通常我们没那么幸运 ;)
private headers = new Headers('Content-Type': 'application/json', 'Access-Control-Allow-Origin': 'https://dinstruct-d4b62.firebaseio');
当然现在它正在返回一个空洞的承诺......调试继续深入思考下巴划痕的表情符号
我可以在我的脑海中看到那个表情符号 :D 我说你需要启用 cors(在服务器端设置标头),而不是在 Angular 中 :)
是的,我知道,但由于某种原因,在 Angular 中启用它实际上确实清除了 CORS 错误,我现在正在接收 JSON 数据(它只是被转换为一个空的承诺)所以即使这在技术上不应该修复它,它有效,所以我不会质疑它。【参考方案3】:
在你有导入[]的 AppModule.ts 中,你会导入 HttpClientInMemoryWebApiModule 喜欢 =>
HttpClientInMemoryWebApiModule
.forRoot(
InMemoryService, dataEncapsulation: false
),
现在这里发生的情况是,您的应用程序正在内存中 Web API 中搜索公共 API 只是为了解决这个问题,只需通过将传递未知 Url 设置为 true 来告诉内存模块不要这样做 喜欢 =>
HttpClientInMemoryWebApiModule
.forRoot(
InMemoryService, dataEncapsulation: false, passThruUnknownUrl: true
)
【讨论】:
以上是关于Angular4为存在并公开服务的json数据提供404的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java 通过 Web 服务以 JSON 格式公开数据?
添加服务失败。服务元数据可能无法访问。确保您的服务正在运行并公开元数据。 WCF 错误