【问题标题】:How to solve the HTTP error 200, SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse如何解决 HTTP 错误 200, SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse
【发布时间】:2018-03-12 18:22:54
【问题描述】:

谁能帮我解决这个问题?我被困了2天,....我真的不知道如何解决它....我使用angular cli / angular5和expressjs构建了一个网页(包含一个表格)。我使用 mongoose mongodb 作为数据库。在本地一切正常。但是当我上传 dist 文件夹并将其部署到 azure web 应用程序时,它的表是空的。 错误日志如下所示:

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "https://stringfr.azurewebsites.net/book", ok: false, …}
   error:
   error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse
    HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
    message: "Http failure during parsing for https://stringfr.azurewebsites.net/book"
    name:"HttpErrorResponse"
    ok:false
    status:200
    statusText:"OK"

这是我的临时网站:“https://stringfr.azurewebsites.net”。您可以通过检查检查完整的错误日志。

我认为这与 book.component.ts 中的这一行有关。 在这里,我从数据库中获取数据并在一个简单的 html 表上使用它。 注意 book_value 只是我获取更多结构化数据的接口。

this.http.get<book_value>('/book').subscribe (
  data => this.books = data
);

这里是我初始化“/book”的地方。 在 app.js 中

var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');


var book = require('./routes/book');
var app = express();
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
//mongoose.connect('put ur own mongodb')
  // .then(() =>  console.log('connection succesful'))
   //.catch((err) => console.error(err));
mongoose.connect('mongodb://localhost/mean-angular5')
  .then(() =>  console.log('connection succesful'))
  .catch((err) => console.error(err));


app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended':'false'}));
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/books', express.static(path.join(__dirname, 'dist')));
app.use('/book', book);

在 ./routes/book.js 中

var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Book = require('../models/Book.js');

/* GET ALL BOOKS */
router.get('/', function(req, res, next) {
  Book.find(function (err, products) {
    if (err) return next(err);
    res.json(products);
    console.log(products);
    console.log("products info above");
    console.log(res);
  });
});

这是我在 ../models/Book.js 中的架构:

var mongoose = require('mongoose');

var BookSchema = new mongoose.Schema({
  timestamp: String,
  question : String,
  answer : String
 });
 module.exports = mongoose.model('Book',BookSchema );

因为我使用的是 dist 文件夹。我使用这个 web.config。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico|.svg|.eot|.woff|\​.woff2)).*$" />
          <conditions logicalGrouping="MatchAll"></conditions>
          <action type="Rewrite" url="/" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
    <staticContent>
      <remove fileExtension=".svg" />
      <remove fileExtension=".eot" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
  </system.webServer>
</configuration>

注意:Azure 日志流上没有显示错误。 这是我的 app.module:

const appRoutes: Routes = [
  {
    path: 'books',
    component: BookComponent,
    data: { title: 'Book List' }
  },
  { path: '',
    redirectTo: '/books',
    pathMatch: 'full'
  }
];

@NgModule({
  declarations: [
    AppComponent,
    BookComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    CalendarModule,
    BrowserAnimationsModule,
    FormsModule,
    AccordionModule,
    PanelModule,
    ButtonModule,
    RadioButtonModule,
    DataTableModule,
    MultiSelectModule,
    DropdownModule,
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

【问题讨论】:

  • 您的图书路线似乎无法访问。 stringfr.azurewebsites.net/book 不起作用。也许您拥有它,因此无法看到常规的 http 请求,但如果您这样做,出于故障排除的原因,您可能希望将其关闭。然后就可以看到json长什么样了。
  • 实际上,如果您阅读错误,您会发现这不是 /book 返回的直接 json 字符串。它是一堆 HTML 和 JavaScript 之类的东西。这就是你的问题所在。
  • 这和这个有关系吗:this.http.get('/book').subscribe (data => this.books = data);因为这是我唯一使用“/book”的地方,所以“/book”正在处理获取请求以从数据库中获取所有图书数据。
  • 还是dist文件夹有问题?
  • 我不知道。我建议您检查以确保您的路线设置正确。这似乎是一个路由问题。尝试查看此文档。 angular.io/guide/router

标签: node.js express httpclient azure-web-app-service angular5


【解决方案1】:

免责声明:我从未使用过 Azure。

在我看来,Azure 正在将所有请求重写为 /,并在每条路径上提供 Angular 的 index.html。

这些类型的重写规则通常如何工作:

  1. 请求进来
  2. Azure 解析请求,并查看是否有任何规则适用。如果是这样,它会根据重定向更改请求 URL。
  3. 新编辑的请求 URL 被发送到 Express。
  4. Express 以编辑后的请求 URL 的结果进行响应。

在我看来,就像在第 2 步中 Azure 将 /book 重写为 /,然后 /book URL 永远不会命中。

我建议您先尝试删除重写规则,然后查看/book URL 是否发送了正确的 JSON 响应。

如果没有,请检查带有斜杠的/book/ 是否发送正确的响应。如果是,而 /book 不是,添加 a 5-line middleware 以使 Express 认为 /book/book/ 具有相同的含义。

【讨论】:

  • 非常感谢,我会尽量做到以上。
  • 我试过了,但是在这两种情况下,它都会给出:“您要查找的资源已被删除、名称已更改或暂时不可用。”我可以通过'/'访问表格,但我不能再在'/books'中这样做了。我想我需要重写它才能正确读取 dist 文件夹。仍然感谢您回答我的问题。
【解决方案2】:

嗯,在 Azure 中,您的应用程序在 Microsoft IIS 上运行,/book 是一个快速路由,它是一个后端 Node.js 应用程序,它应该由 IIS 模块 iisnode 执行。因此,您需要编辑 web.config 文件以将 CGI 处理程序设置为如下内容:

<handlers>
    <!-- Indicates that the app.js file is a node.js site to be handled by the iisnode module -->
    <add name="iisnode" path="app.js" verb="*" modules="iisnode"/>
</handlers>

并且还添加以下规则来告诉入口点是什么:

<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
     <conditions>
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
     </conditions>
     <action type="Rewrite" url="app.js"/>
</rule>

并添加这个来告诉静态内容在哪里:

<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
     <action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>

另见:

【讨论】:

  • 我在上面试过了。当我部署 dist 文件夹时,错误日志仍然相同。它仍然有相同的错误,并且最后添加与我的原始代码冲突,它也给了我 404。但是,我认为你是对的......它有与web.config有关。我认为当我尝试从数据库中获取数据时 app.js 没有运行。谢谢你的回答,
  • 编辑:它不是 404,它的 net::ERR_ABORTED。
  • 如果可以的话,你能看看我的代码吗:这是我的 github 链接:github.com/QiiLin/Personal-Project-for-Chatbot 或者你能链接我一些资源让我看看。我有点知道是什么导致了这个问题,但不知道如何解决它。是否有一个很好的指导方针来构建一个有效的 web.config?
【解决方案3】:

您是否尝试过将https://stringfr.azurewebsites.net/book 粘贴到您的浏览器并查看返回的内容?

如果不是 JSON,那是你的问题。

【讨论】:

  • 它说 NavigationError {id: 1, url: "/book", error: Error: Cannot match any routes。我已经知道了......这是我的问题,但我无法解决,这就是为什么我在这里问这个问题......
猜你喜欢
  • 2019-05-23
  • 2021-09-30
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多