micro service
Authentication và authorization là một trong số các generic domain của một hệ thống. Trong microservices, người ta cũng thường tách biệt authentication và authorization ra tầng API Gateway. Khi đó, các microservices không phải xử lý authentication nữa mà chỉ cần tập trung vào giải quyết các bài toán nghiệp vụ chính của doanh nghiệp mà thôi.
api - laravel
Do là hai project riêng biệt nên B muốn dùng chung được access token của A thì có lẽ bạn cũng sẽ cần phải mang APP_KEY của A sang dùng cho B cũng như implement thêm cơ chế authentication/authorization y hệt như trên A. -> Bạn có thể đóng gói hết code cho việc authentication của A thành một composer package rồi cài sang cho B.
Ngoài ra cũng có thể ứng dụng các phương án khác như:
- Tách phần authentication / authorization của A ra xử lý tại tầng API Gateway. A và B cùng đứng sau API Gateway thì không cần phải xử lý lại authentication nữa.
- Cũng có thể dùng kiểu tạo middleware trên B gọi ngược sang A để lấy thông tin. Tuy nhiên điểm hạn chế của nó là B sẽ bị phụ thuộc vào A. Cùng với đó là B cũng cần triển khai trên chung private network vì nếu từ B mà gọi sang A qua public domain thì coi như bỏ vì response time sẽ tăng lên rất nhiều.
- SSO, Oauth2, OIDC...
Reset select option khi click back history
Vấn đề em đang gặp phải là do trình duyệt lưu trạng thái của trang web như dữ liệu của các thẻ input, vị trí cuộn, trạng thái của các phần tử DOM... Các dữ liệu này được restore khi nhấn nút Back.
Anh nghĩ em hãy thử mấy cách sau:
- Trang nào ko muốn cache thì server thêm header yêu cầu ko no-cache chặng hạn
- Dùng JavaScript bắt sự kiện tải trang rồi thực hiện reset về default value
- Không render ssr cái field input đó, mà thử render dưới client side xem?
Nhưng mà anh nghĩ là có thể nó lưu các trạng thái này vào memory hoặc đâu đó, nên cách 1 và 3 có thể không có tác dụng. Cách 2 thì bắt sự kiện pageshow như sau:
<form method="GET" url="/">
<input name="submitted" value="default" />
<button type="submit">Submit</button>
</form>
<script>
window.addEventListener('pageshow', () => {
const input = document.querySelector('input');
const url = new URL(location);
if (input && !url.searchParams.get('submitted')) {
input.value = 'default';
}
});
</script>
ZSH from BASH on WSL
Một vài câu lệnh của bạn ở đây là câu lệnh như nào ấy nhỉ? Nếu chúng là alias thì bạn cần khai báo các alias này trong file ~/.zshrc nữa thì khi dùng zsh mới nhận.
Còn nếu không phải alias mà lại không tương thích với ZSH thì bạn có thể thứ các cách sau:
- Nếu command dài -> tạo file
*.sh
để chạy - Hoặc nếu ngắn thì chạy bới bash bằng flag
-c
:
bash -c "echo Your Bash script"
- Hoặc là mở bash shell để chạy command, xong rồi lại exit ra ZSH:
bash
- Hoặc convert command đó sang cú pháp của ZSH
Đưa media từ rails assets vào trong file javascript
File của em đã được public đúng URL chưa? Anh đoán là chưa. Em đưa nó vào thư mục public nhé. http://localhost/assets/audio/drumsticks.mp3
Với cả, em dùng lệnh setInterval với this như kia sẽ lỗi đó. Vì this sẽ out of scope và còn không tồn tại. Em dùng kiểu này:
setInterval(this.beat.play.bind(this.beat), 1000)
Lối loop khi sử dụng setInterval
Khả năng lỗi do dòng này nè em:
this.timer = setInterval(this.beat.play(), (60 / this.bpm) * 1000)
Cái argument đầu tiên phải là một function
để nó thực thi trong mỗi lần lặp. Còn trong code kia thì tại dòng setInterval
cái hàm play
nó đã chạy luôn mất rồi. Em sửa lại kiểu như sau:
this.timer = setInterval(this.beat.play.bind(this.beat), (60 / this.bpm) * 1000);
// hoặc thế này:
this.timer = setInterval(() => this.beat.play(), (60 / this.bpm) * 1000);
https://developer.mozilla.org/en-US/docs/Web/API/setInterval
Khi triển khai ứng dụng Docker CI/CD gặp bug hotfix thì nên xử lý thế nào cho ấm êm cả nhà?
- Nếu là lỗi cực kỳ nghiêm trong thì bạn cần xử lý rollback về phiên bản cũ ngay. Bạn có thể lên CI retry lại step deploy trong bản build của lần release trước đó. Hoặc cũng có thực hiện thủ công bằng tay.
- Nếu lỗi không quá nghiêm trọng mà có thể fix nhanh được thì tạo PR hotfix merge đồng thời cho cả prod và môi trường kiểm thử staging.
Đa ngôn ngữ trong php
Thay vì sử dụng file js hoặc json, bạn hãy sử dụng file .php và require nó như code PHP bình thường. Như vậy phần translations sẽ là một phần của source code PHP. Bạn không phải lo lắng về vấn đề đọc file_get_content vì thường trên server sẽ cấu hình opcache.
Best way để upload 100k rows file excel vào database
Có nhiều hướng tiếp cận:
- Sử dụng JS để đọc file excel và hiển thị trực tiếp nội dung file trên browser. Khi hiển thị thì đồng thời thực hiện validate dữ liệu và báo lỗi luôn. Chỗ này có thể cho sửa trực tiếp dữ liệu ngay trên browser. Khi nhấn upload thì không gửi file lên server mà sẽ gửi dữ liệu theo từng batch, VD: Đọc một cục dữ liệu theo từng 5, 10, 50 rows để gửi lên server. Nếu server có lỗi thì trả về thông tin cần thiết cho browser như lỗi row nào, do đâu để browser hiển thị lại trên màn hình.
- Vẫn đọc file excel trên browser & validate + hiển thị lỗi luôn. Sau khi user fix hết lỗi thì cho upload file lên server.
- Upload file thẳng lên server:
- Server lưu lại file đồng thời cũng lưu một record vào database, kiểu như: File A, Status: Queued, Created Time, Completed Time.
- Đẩy một job
UploadExcelFile
vào queue. Bạn có thể dùng queue id để tạo channel web socket hiển thị kết quả xử lý realtime nếu cần. Job này có nhiệm vụ là thực hiện đọc dữ liệu từ file excel theo từng batch 100 rows /1 lần đọc (các lib thường có option này). Thực hiện validate từng row, cái nào hợp lệ thì lưu, cái nào lỗi thì có thể bắn về cho client qua web socket hoặc lưu lại ra file excel có cấu trúc tương tự. Job chạy xong thì cập nhật lại Status trong Database, Tên File kết quả các dòng lỗi nếu có.
Nhìn chung là có thể làm như trên hoặc phối kết hợp các cách trên hoặc cũng có thể thêm thắt các tùy biến khác sao cho phù hợp với tình hình, kiến trúc hệ thống và cả tiến độ dự án.
Build dự án ra file dist thì khi reload lại trang bị lỗi.
Nó bị lỗi khả năng là app bạn đang làm là SPA mà trên server bạn chỉ cấu hình routing cho duy nhất trang root /. Điều này sẽ lý giải cho việc:
- Khi bạn vào trang chủ bằng URL trên trình duyệt vẫn xem được.
- Bạn click vào link trang khác thì vẫn xem được. Việc chuyển trang trên browser thực chất chỉ là client-side navigation do Vue Router thực hiện. Do đó, nội dung bạn xem được là Vue App tạo ra, không phải kết quả từ server trả về.
Bạn cần cấu hình Rewrite URL cho Apache trên hosting để xem được nhé. Mà nếu app chỉ là SPA thì bạn nên upload lên Github Pages hoặc các dịch vụ cloud khác có lẽ sẽ đỡ tốn chi phí hơn là dùng hosting mà lại được dùng sẵn CDN từ các dịch vụ đó.
Hỏi về tối ưu messenger chat trong vuejs
Cần gì phải phức tạp thế, bạn copy thẳng cái script embed của facebook rồi chèn vào cuối trang ấy. Xong thêm attribute này cho phần embed chatbox để nó hiện mỗi icon message, hộp chat chỉ hiện khi người dùng click vào icon.
greeting_dialog_display = icon
<!-- Messenger Chat Plugin Code -->
<div id="fb-root"></div>
<div id="fb-customer-chat" class="fb-customerchat"></div>
<script>
var chatbox = document.getElementById('fb-customer-chat');
chatbox.setAttribute("page_id", "PAGE-ID");
chatbox.setAttribute("greeting_dialog_display", "icon");
</script>
<script>
window.fbAsyncInit = function() {
FB.init({
xfbml : true,
version : 'API-VERSION'
});
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
ai giúp em lỗi terminal ảo ma này ở vscode
Bạn thử đổi shell sang dùng cmd/powershell xem có bị tình trạng tương tự nữa không?
Cách tạo deeplink để nhảy đến màn hình trên app?
Bạn có thể dùng Firebase Dynamic Links nhé. https://firebase.google.com/docs/dynamic-links
Kinh nghiệm xin duyệt project trên Google Console
Project trên Google Console thì có phải đợi Google review gì đó thì mới dùng được đâu nhỉ? Bạn cứ tạo project, tạo credentials rồi enable những bộ API bạn cần dùng là sử dụng được ngay mà.
viblo SEO for a blog
- Website của bạn cần có một trang sitemap trả về dạng XML chứa danh sách các trang trong website của bạn mà bạn muốn Google quét, cũng như là tần suất quét.
- Bạn gửi link trang sitemap cho Google Search Console, sau đó thì Google Bot sẽ đều đặn scan các trang trên website của bạn để tạo index cho các thông tin tìm kiếm. m.
- Trang sitemap có thể là một file sitemap.xml tĩnh, hoặc cũng có thể là nội dung XML được tự động tạo mới mỗi khi bạn đăng thêm bài viết mới.
Nội dung XML được follow theo hướng dẫn tại đây: https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap
Làm cách nào để remove token của user trong localStorage nếu token hết hạn?
- Khi browser request lên server, server check thấy token hết hạn thì trả về response báo hết phiên đăng nhập. VD: Response 440 - Session Expired
- Dưới client, nếu nhận response về với status code là 440 sẽ hiểu là hết phiên đăng nhập thì tự xóa local storage.
Maximum execution time of 60 seconds exceeded
Lỗi này anh em hay nói vui với nhau là "code thối", dẫn tới hiệu năng kém và chạy quá thời gian cho phép của server. Để làm nó chạy lại được thì rất dễ - đó là config PHP bằng mấy tham số như dưới đây:
- max_execution_time
- memory_limit
Việc sửa đổi các cấu hình thì sẽ gây ra các vấn đề kéo theo như một request được server xử lý quá lâu sẽ dẫn tới chiếm hết các tài nguyên server - nó sẽ thành điểm tuyệt vời để hacker nhắm vào giúp DOS server của bạn dễ hơn. Nếu config một con số chưa đủ cao (theo thời gian số lượng dữ liệu tăng lên) thì lỗi sẽ lại tái diễn.
Các trên không giải quyết triệt để vấn đề. Vấn đề cốt lõi ở đây là chất lượng code. Bạn nên refactor lại code, áp dụng thêm các giải pháp khác nhau như: Paginate, cache, lazy-loading... để code xử lý trả ra kết quả thật nhanh. Từ đó dù dữ liệu nhiều hay ít thì server vẫn hoạt động ổn định.
Giúp em về Cron job Task Scheduler trong laravel với các anh :(((
Bạn sử dụng Task Scheduler của Laravel là đúng rồi nhé. Kết hợp dùng Task Scheduler + Artisan Command sẽ là sự lựa chọn tuyệt vời. Cách thức thực hiện thì sẽ làm như sau:
- Tạo một Artisan Command theo hướng dẫn: https://laravel.com/docs/9.x/artisan VD: SendDailyReport
- Viết code logic của bạn vào trong method
handle
trong command - Cấu hình Task Scheduler để Laravel tự động chạy command trên theo hướng dẫn: https://laravel.com/docs/9.x/scheduling#scheduling-artisan-commands
- Cấu hình Crontab trên server để server tự động chạy Task Scheduler của Laravel
Bạn làm theo các hướng dẫn của mình bên trên là được.
Làm thế nào biết record được tạo ra khi nào?
Nếu bạn không có cột date nào để tự lưu thì không có cách nào để biết record đó tạo khi nào đâu nhé. Giờ chỉ có nước là tìm qua các bảng liên quan xem có chỗ nào lưu date mà phù hợp để lấy ra dùng thay thế thôi.
Kiểu như bảng user không có cột created_at (thời gian tạo) nhưng lại có một bảng activation_email_logs có cột sent_at (thời gian mail xác thực tạo tài khoản được gửi) thì có thể bê cái sent_at về làm cho created_at để chống cháy.
Hỏi về xây dựng website
Dùng luôn wordpress nha bạn.