2015-07-09 28 views
18

Tôi biết có những câu trả lời khác cho vấn đề này nhưng dường như chúng có sự thận trọng.Định tuyến góc trong HTML5mode với Node.js

This one causes a redirect, có thể gây tử vong cho ứng dụng giao diện người dùng của tôi sử dụng Mixpanel và tải hai lần Mixpanel sẽ xảy ra lỗi Kích thước ngăn xếp cuộc gọi tối đa đã vượt quá trong trình duyệt.

This one uses sendFile cá nhân tôi không thể làm việc. Đang cố gắng chẩn đoán điều đó, tôi chỉ được khuyên sử dụng express.static().

Mã hiện tại của tôi trông giống như sau:

home.js - Một số tuyến đường, tuyến cuối cùng dự định là trang web mặt trước.

var indexPath = path.resolve(__dirname, '../' + process.env.PUBLIC_FOLDER) 

router.get('/:user/:stream/:slug', function(req, res, next) { 

    if (req.headers['user-agent'].indexOf('facebook') != -1) { 
     // stuff to handle the Facebook crawler 
    } else return next() 
}) 

router.get('/*', function(req, res) { 
    express.static(indexPath) 
}) 

server.js - cấu hình nút/bày tỏ

app = express(); 

app 
    .use(morgan('dev')) 
    .use(bodyParser.urlencoded({ limit: '50mb', extended: true })) 
    .use(bodyParser.json({ limit: '50mb' })) 
    .use('/api', require('./routes/usersRoute.js')) 
    .use('/', require('./routes/home')) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

http 
    .createServer(app).listen(process.env.PORT) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

Một số biết thêm

Lý do bạn có thể thấy tôi đang cố gắng để sử dụng express.static() là bởi vì khi tôi sử dụng res.sendfile() Tôi gặp sự cố like this one nơi bảng điều khiển cho biết Unexpected token '<'. Thật không may câu trả lời không chỉ định sửa lỗi chính xác và người hỏi cũng không cho biết họ đã khắc phục sự cố nhưng không chia sẻ câu trả lời.

Trong cuộc thử nghiệm và lỗi của tôi, tôi đã thêm một số chi tiết để thể hiện, như thế này

.use('/app/app.js', express.static(indexPath + '/app/app.js')) 
.use('/app/views', express.static(indexPath + '/app/views')) 
.use('/app/controllers', express.static(indexPath + '/app/views')) 
.use('/app/directives', express.static(indexPath + '/app/views')) 
.use('/app/vendor', express.static(indexPath + '/app/vendor')) 
.use('/js', express.static(indexPath + '/js')) 
.use('/css', express.static(indexPath + '/css')) 
.use('/fonts', express.static(indexPath + '/fonts')) 
.use('/images', express.static(indexPath + '/images')) 
.use('/api', require('./routes/usersRoute.js')) 
.all('/*', require('./routes/home')) 

Và trong home.js tuyến My Files thêm này

router.get('/*', function (req, res) { 
    res.status(200).set({ 'content-type': 'text/html; charset=utf-8' }) 
    .sendfile(indexPath + '/index.html') 
}) 

Và trong trình duyệt tôi có thể nhìn thấy tất cả của tôi các tệp đang tải, nhưng với lỗi < ở trên. Tôi thấy con đường này /*/ đang được gọi là hàng trăm lần khi tôi làm mới vì vậy tôi nghĩ rằng các cấu hình .use('...', ...) đang bị bỏ qua.


Đây là một ví dụ khác được Jonas yêu cầu bên dưới.

var indexPath = path.resolve(__dirname, process.env.PUBLIC_FOLDER) 

mongoose.connect(process.env.MONGOLAB_URI) 

app = express(); 

app 
    .use(morgan('dev')) 
    .use(bodyParser.urlencoded({ limit: '50mb', extended: true })) 
    .use(bodyParser.json({ limit: '50mb' })) 
    .use('/api', require('./routes/usersRoute.js')) 
    .use('/', require('./routes/home.js')) 
    .use(express.static(indexPath)) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

Tôi cũng đã thực hiện tương tự mà không có đường dây .use('/', require('./routes/home.js')) để thử thu hẹp mọi sự cố nhưng kết quả tương tự. Trang sẽ tải nếu tôi có # trong URL, nhưng trình duyệt sẽ xóa # (cho đến nay rất tốt). Nhưng nếu tôi nhấn làm mới, hoặc đặt trong URL bằng tay, sans-hashbang, nó sẽ cung cấp cho một lỗi như Cannot GET /home/splash, nơi /home/splash là bất cứ con đường nào tôi sẽ.

+0

Làm cách nào để thêm tiền thưởng vào tài khoản này? Đã 4 ngày rồi ... – Noah

+0

Tôi không phải là chuyên gia thể hiện, nhưng tôi chưa bao giờ thấy ai gặp lỗi khi theo dõi các mẫu trong [FAQ-Router FAQ] (https://github.com/angular-ui/ui-router/wiki/Câu hỏi thường gặp), hiển thị bằng 'app.all' thay vì' router.get'. – Claies

+0

Bạn đã kiểm tra các đường dẫn được chuyển đến 'express.static' có hợp lệ không? Giá trị của 'indexPath' là gì? – manji

Trả lời

12

Bạn có thể đang sử dụng phần mềm trung gian nhanh theo cách không đúng. Nhìn vào documentation nói với tôi rằng ví dụ đoạn mã sau

.use('/images', express.static(indexPath + '/images')) 

Phục vụ bất kỳ tập tin trong thư mục indexPath + '/images' với URL như vậy:

http://localhost:3000/images/kitten.jpg 
http://localhost:3000/images/logo.png 
http://localhost:3000/images/whatever.jpg 

Là những gì bạn mong đợi nó để làm gì?

Đề nghị của tôi là thay đổi từ

.use('/', require('./routes/home')) 

để

.use(express.static(indexPath)) 

Bởi vì theo các tài liệu, nó sẽ phục vụ tất cả các file tĩnh trong thư mục indexPath từ đường dẫn gốc, aka. không có tiền tố.

Tôi nghĩ rằng đó là tất cả những gì tôi có thể trợ giúp với thông tin bạn đã cung cấp cho đến thời điểm này. Nếu điều đó không làm được điều này, có lẽ bạn có thể chia sẻ một số ví dụ mã nhỏ mà tôi có thể sử dụng để tự tạo lại nó.

CẬP NHẬT

Ok. Tôi đã cố gắng tạo ra một ví dụ đơn giản về nó. Tôi đã làm cho nó hoạt động theo cách sau. cấu trúc thư mục của tôi là như thế này:

|- index.js 
|- public/ 
|---- index.html 
|---- test.html 
|---- main.js 
|---- angular.js 
|---- angular-route.js 

index.js là server node. Hãy chú ý đến đơn đặt hàng của tuyến đường. Tôi cũng đã thêm một số ví dụ /home/login để làm rõ cách thêm các tuyến máy chủ khác không nên đi qua góc cạnh.

var http = require('http'); 
var express = require('express'); 
var app = express(); 

app 
    .use(express.static('public')) 
    .get('/home/login', function (req, res) { 
     console.log('Login request'); 
     res.status(200).send('Login from server.'); 
    }) 
    .all('/*', function (req, res) { 
     console.log('All'); 
     res 
      .status(200) 
      .set({ 'content-type': 'text/html; charset=utf-8' }) 
      .sendfile('public/index.html'); 
    }) 
    .on('error', function(error){ 
     console.log("Error: \n" + error.message); 
     console.log(error.stack); 
    }); 

http 
    .createServer(app).listen(8080) 
    .on('error', function(error){ 
     console.log("Error: \n" + error.message); 
     console.log(error.stack); 
    }); 

console.log('Serving app on port 8080'); 

index.html là khá đơn giản.

<!doctype html> 
<html> 
<head> 
    <title>Angular HTML5 express test</title> 
    <script type="text/javascript" src="angular.js"></script> 
    <script type="text/javascript" src="angular-route.js"></script> 
    <script type="text/javascript" src="main.js"> 
    </script> 
</head> 
<body ng-app="app"> 
    <div ng-view></div> 
</body> 
</html> 

main.html chỉ thêm một số nội dung. Quan trọng là liên kết để /test

<div> 
    <h1>This is just a {{val}}</h1> 
    <button ng-click="clicked()">Click me!</button> 
    <span>You clicked {{counter}} times</span> 
    <a href="/test">test me!</a> 
</div> 

test.html là thực sự không liên quan

<div> 
    <h4>What a beautiful day to test HTML5</h4> 
</div> 

main.js đang làm cốt lõi làm việc html5 góc

angular.module('app', ['ngRoute']) 
    .config(function($locationProvider) { 
     $locationProvider 
      .html5Mode({ 
       enabled: true, // set HTML5 mode 
       requireBase: false // I removed this to keep it simple, but you can set your own base url 
      }); 
    }) 
    .config(function($routeProvider) { 
     $routeProvider 
      .when('/test', {templateUrl: 'test.html', controller: function() { 
       console.log('On /test.'); 
      }}) 
      .when('/', {templateUrl: 'main.html', controller: 'MyTestCtrl'}) 
      .otherwise('/'); 
    }) 
    .controller('MyTestCtrl', function ($scope) { 
     self = $scope; 
     self.val = 'TeSt'; 
     self.counter = 0; 
     var self = self; 
     self.clicked = function() { 
      self.counter++; 
     }; 
    }); 
+0

Khi tôi sử dụng 'express.static' với chế độ HTML5 trong Angular, tôi nhận được lỗi 'Không thể GET [đường dẫn đến trang]' sau khi làm mới hoặc nhập URL theo cách thủ công. Nếu tôi thêm '#' trở lại URL, tôi có thể xem trang và # sẽ bị xóa. – Noah

+0

@Noah Bạn có thể tạo một Ví dụ? – Jonas

+0

Bạn đang nói với tôi rằng bạn biết chắc chắn rằng '.use (express.static (indexPath))' hỗ trợ HTML5? Bởi vì nó không có vẻ. Nó hoạt động cho đến khi tôi nhấn refresh, thứ vi nó nói 'Không thể GET/home/splash'. Nếu tôi đặt '#' trở lại trong URL, nó tải và loại bỏ '#', nhưng làm mới lại sẽ cho lỗi một lần nữa. – Noah

5

thay vì:

router.get('/*', function(req, res) { 
    express.static(indexPath) 
}) 

do

router.get('/:anyreq', function(req, res) { 
    express.static(indexPath) 
}) 

giữ nó ở cuối tệp tuyến.

+0

Tôi nhận được 'Không thể GET/home/login' khi sử dụng đường dẫn và' Không thể GET/'khi sử dụng' # 'trong đường dẫn. – Noah

0

Dường như có thể có vấn đề với yêu cầu AJAX của bạn.
Tôi thường thiết lập các tuyến đường của tôi như thế này:

app.use(express.static(path.join(__dirname, "./public"))); app.use("/", require(path.join(__dirname, "./routes")));

và thực hiện cuộc gọi ở đầu phía trước với templateUrl: "/templates/home.html" trong một chỉ thị

hoặc $http.get("/images").success(...).error(...) sử dụng $ http.

Trong trường hợp mẫu, ứng dụng sẽ đi vào thư mục công cộng, sau đó là mẫu đường dẫn và phân phát tệp html. Trong trường hợp $ http, tôi chỉ định lộ trình để ứng dụng kiểm tra thư mục công cộng, không nhìn thấy đường dẫn hình ảnh và vì vậy hãy chuyển sang bộ định tuyến. Trong bộ định tuyến, tôi có một số router.get("/images", function (req, res, next) { res.sendFile(...); hoặc res.send({(data)}) }) sẽ gửi tệp mà tôi cần trở lại giao diện người dùng nơi nó bị xử lý thành công.

+0

Tôi đang sử dụng' $ http' trên giao diện người dùng và khai báo ' templateUrl' như bạn giải thích.Bạn có đang sử dụng 'html5Mode' không? Bạn có thể xác nhận nó hoạt động với Express không? – Noah

+0

Tôi đang sử dụng góc cạnh và thể hiện với thiết lập đó.Trong bộ định tuyến tĩnh, bạn cần cung cấp đường dẫn tương đối (tức là' đường dẫn. join (__ dirname, "public") ') –

Các vấn đề liên quan