How to solve the HTTP error 200, SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse

匿名 (未验证) 提交于 2019-12-03 00:46:02

问题:

Can anyone help me with this issue ? I am stuck on this for 2 days,....I really do not how to fix it....I built a web page(contains a table) using angular cli/angular5 and expressjs. I use mongoose mongodb as the database. Everything working fine on local. But When I uploaded the dist folder and deployed it to the azure web app, its table is empty. The error log looks like this:

Here is my temp website:"https://stringfr.azurewebsites.net". you can check the full error log by inspect.

I think this is something to do with this line in the book.component.ts. Here I get data from the database and use it on a simple html table. Note book_value is just a interface for me to a get a more structural data.

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

Here is where I init the '/book'. in 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); 

In the ./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);   }); }); 

Here is my schema in the ../models/Book.js:

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

Since I am using dist folder. I use this web.config.

Note: There is not error showing on the azure log stream. Here is my 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 { } 

回答1:

Well, in Azure, your app runs on Microsoft IIS, and /book is an express route which is a backend Node.js app and it should be executed by the IIS module iisnode. So, you'd need to edit your web.config file to set the CGI handler to something like this:

<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> 

And also add the following rule to tell what the entry point is:

<!-- 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> 

And add this to tell that where the static content are:

<!-- 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> 

See also:



回答2:

Disclaimer: I've never used Azure.

It looks to me like Azure is rewriting all requests to / and serving Angular's index.html on every path.

How these kinds of rewrite rules usually work:

  1. Request comes in
  2. Azure parses the request, and sees if any rules apply. If so, it changes the request URL based on the redirect.
  3. The new edited request URL gets sent to Express.
  4. Express responds with the edited request URL's result.

It looks to me like when in step 2 Azure rewrites /book to /, then the /book URL is never hit.

I suggest you first try removing the rewrite rule and seeing if the /book URL sends the correct JSON response.

If it does not, check if /book/ with the trailing slash sends the right response. If it does, and /book does not, add a 5-line middleware to make Express think /book and /book/ mean the same thing.



回答3:

have you tried pasting https://stringfr.azurewebsites.net/book into your broswer and seeing what returns?

If it's not JSON, that's your problem.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!